// TextHandle.cpp: implementation of the CTextHandle class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "TextHandle.h"
#include "Psola.h"
#include "TDPSOLA_Console.h"
#include <stdlib.h> 
#include "MyConstants.h"
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CString CTextHandle::m_csError;
int		CTextHandle::m_nErrorCode = TH_NOERROR;
CString CTextHandle::CsDirectoryOfFile = "";
CString CTextHandle::CS_DBFileName = "";
CString CTextHandle::cs_DBSylTextFileName = ""; // duong dan toi csdl text am tiet;
ofstream txtFile2;
CTextHandle::CTextHandle()
{
	txtFile2.open("txt_TextHandle.txt");
	txtFile2.close();
}

CTextHandle::~CTextHandle() 
{
	this->Empty();
}
/******************************************************************************************************************/
// kiem tra input co phai la so ko? thaodv 250111
BOOL CTextHandle::IsNumeric(LPCTSTR lpBuf,WORD wLen)
{
	for(int i = 0;i < wLen; i++)
	{
		if( (lpBuf[i] != '0')&&(lpBuf[i] != '1')&&(lpBuf[i] != '2')&&(lpBuf[i] != '3')&&(lpBuf[i] != '4')
			&&(lpBuf[i] != '5')&&(lpBuf[i] != '6')&&(lpBuf[i] != '7')&&(lpBuf[i] != '8')&&(lpBuf[i] != '9'))
			return FALSE;
	}
	return TRUE;
}
/******************************************************************************************************************/
CString CTextHandle::GetLastError(int *nErrorCode)
{
	if(nErrorCode) *nErrorCode = m_nErrorCode;
	switch(m_nErrorCode)
	{
		case TH_INDEXOVERFLOW :			return "Index Overflow";
		case TH_UNITNOTFOUND	:		return m_csError;
		case TH_UNITNOTPAIR :		return m_csError;
		case TH_LENNOTNUMERIC	:		return m_csError;
		case TH_FONOTNUMERIC :			return m_csError;
		case TH_SILENCELENNOTNUMERIC :	return m_csError;
	}
	return "No Error";
}
/******************************************************************************************************************/
BOOL CTextHandle::ParseText(CString &cs)
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// The variables used for analyzing the context of a syllable.
	// Adding: 19-12-2006
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////

	BYTE BTypeOfPhrase;	
	BYTE bUnitType;  // 4 Syllable
					// 2 DemiSyllable
					// 1 Dephone
					// 0 Phone
					// 3 Initial - Final Parts
					// 5 all
	CArray<UNITINFOFULL,UNITINFOFULL> SyllableArray;
	CStringArray SylArray; //test - ko thay dung trong cau lenh nao; thaodv 180111
	UNITINFOFULL SyllableElement;
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
	int nPhraseBegPos, nPhraseEndPos, nSyntagmBegPos, nSyntagmEndPos, 
		nWordBegPos, nWordEndPos, nSyllableBegPos, nSyllableEndPos, nStressPos, 
		nPhraseEndPosQuestion, nPhraseEndPosImperative; // nPhraseEndPosQuestion added for demo aniverssary
	int nSylPosInWord, nSylPosInSyntagm, nSylPosInPhrase;
	int nNumOfDash, nNumOfSpace;
	int nPhraseLen, nSyntagmLen, nWordLen;
	int nPhraseLenInSyl, nSyntagmLenInSyl, nWordLenInSyl;
	int i = -1;
	int j = 0;
	int nLen;
	CString csMid, csPhrase, csSyntagm, csWord, csSyllable;
	
//	if(CPsola::BAutoORHandF0 == TRUE)
	BTypeOfPhrase = CPsola::nTypeOfPhrase;
	//cout << "this is starting point of function TextHandle::ParseText(CString &cs) at line 97" << endl; // thaodv 230211
	//cout << cs <<endl; //thaodv 230211
	cs_DBSylTextFileName = CsDirectoryOfFile + '\\' + "FormOfSPESIALS" + '\\' + "ListOfSyllable.tdd";
	LoadSylTextData(cs_DBSylTextFileName); // thaodv 100311
	
	if(CPsola::BSettingInputText == TRUE)
	{
		//LoadDictionary();
		LoadPhoneme();
		LoadVowelAndTone();
		Empty();
		
		int dwBegin, dwEnd;
		CString csTemp, csOut, csF0, csTemp1;
		int dwSize = SyllableArray.GetSize();

		CString csPhoneme[13]			= {"7X","EX","aX","OX","ie","M7","uo","NG","th","tr","NJ","ss","zr"};
		CString csPhonemeConverted[13]  = {"Z", "A", "B", "Q", "I", "U", "Y", "N", "T", "R", "J", "S", "r"};
		
		
		cs.Remove('\r'); cs.Remove('\n');
		nLen = cs.GetLength();
		//nLen is length of input text thaodv 240211
		nPhraseBegPos =0;
		//SylArray.Add("SILP");
		SyllableElement.cUnitName ="SILP";
		SyllableElement.PosInWord =0;
		SyllableElement.PosInSyntagm =0;
		SyllableElement.PosInPhrase =0;
		SyllableElement.Stress = 0;
		SyllableElement.TypeOfPhrase = 0;
		
		SyllableArray.Add(SyllableElement);
		while( nPhraseBegPos + 1 < nLen )
		{
			nPhraseEndPos = cs.Find('.',nPhraseBegPos);// tim vi tri cuoi cung cua cau tran thuat thaodv 280211
			nPhraseEndPosQuestion = cs.Find('?',nPhraseBegPos);//tim vi tri cuoi cung cua cau hoi thaodv 280211
			nPhraseEndPosImperative = cs.Find('!',nPhraseBegPos);// tim vi tri cuoi cung cua cau cau khien thaodv 280211
			
			if((nPhraseEndPos >-1)||(nPhraseEndPosQuestion >-1)||(nPhraseEndPosImperative >-1))
			{
				int nPosMin =-1;
				if (nPhraseEndPos >-1) nPosMin = nPhraseEndPos;
				if (((nPosMin > nPhraseEndPosQuestion)&&(nPhraseEndPosQuestion >-1))||(nPosMin == -1)) nPosMin = nPhraseEndPosQuestion;
				if (((nPosMin > nPhraseEndPosImperative)&&(nPhraseEndPosImperative >-1))||(nPosMin == -1)) nPosMin = nPhraseEndPosImperative;
				
				if(nPosMin == nPhraseEndPos)
				{
					//nPhraseEndPos = nPhraseEndPosImperative;
					if(CPsola::nTypeOfPhrase == 3)	BTypeOfPhrase = 0;
				}
				if(nPosMin == nPhraseEndPosQuestion)
				{
					nPhraseEndPos = nPhraseEndPosQuestion;
					if(CPsola::nTypeOfPhrase == 3)	BTypeOfPhrase = 1;
				}
				if(nPosMin == nPhraseEndPosImperative)
				{
					nPhraseEndPos = nPhraseEndPosImperative;
					if(CPsola::nTypeOfPhrase == 3)	BTypeOfPhrase = 2;
				}



			}
			else 
			{
				if(CPsola::nTypeOfPhrase == 3) BTypeOfPhrase = 0;
			}

			switch(BTypeOfPhrase)
			// dua vao loai cau ma thay doi tan so trung binh va toc do giong doc thaodv 280211

			{
				case 0: fRegister		= 1.0f;
						fSpeakingRate	= 1.0f;
						break;
				case 1: fRegister		= 1.1f;
						fSpeakingRate	= 0.92f;
						break;
				case 2: fRegister		= 1.2f;
						fSpeakingRate	= 0.85f;
						break;
			}
			
			if(nPhraseEndPos == -1)
			{ 
				if (nLen -nPhraseBegPos ==0) break;
				////////////////////////////////////////////////////
				// Extract the phrase of a paragraph.
				////////////////////////////////////////////////////
				csMid= cs.Mid(nPhraseBegPos, nLen - nPhraseBegPos);
				//extracts a substring of length (nLen - nPhraseBegPos) characters from this CString object, 
				//starting at position nPhraseBegPos (zero-based). 
				//The method returns a copy of the extracted substring. thaodv 280211
				////////////////////////////////////////
				// thay the dau tab va hai ki tu trang = 1 ki tu trang, luu cau tach ra duoc vao csPhrase thaodv 280211				
				csMid.Replace('\t',' ');
				cout << "this is csMid" <<csMid << endl;//thaodv 280211 - khong thay goi toi cau lenh nay.
				for(;;)
				{
					int nIsDoubleSpace;
					nIsDoubleSpace = csMid.Replace("  "," ");
					if (nIsDoubleSpace == 0) break;
				}
				///////////////////////////////////////////
				csPhrase = csMid;
				csMid.TrimLeft();
				csMid.TrimRight();
				///////////////////////////////////
				// calculate number of syllable in phrase base on ' ' and '-'
				nNumOfSpace = csMid.Remove(' ');// tra ve so luong dau cach trong cau thaodv 280211
				nNumOfDash	= csMid.Remove('-');
				nPhraseLenInSyl = nNumOfSpace + nNumOfDash +1;
				nSylPosInPhrase =0;
				// tinh toan so luong am tiet trong cau dua vao ' ' va '-'. 
				///////////////////////////////////
				nSyntagmBegPos =0;
				nPhraseLen = csPhrase.GetLength();
				while(nSyntagmBegPos + 1 <nPhraseLen)
				{
					nSyntagmEndPos = csPhrase.Find(',',nSyntagmBegPos);
					if(nSyntagmEndPos == -1)
					{
						if(nPhraseLen - nSyntagmBegPos ==0) break;
						////////////////////////////////////////////////////
						// Extract the syntagm from a phrase.
						////////////////////////////////////////////////////
						if(nSyntagmBegPos > 0)	//SylArray.Add("SIL");
						{
							SyllableElement.cUnitName ="SIL";
							SyllableElement.PosInWord =0;
							SyllableElement.PosInSyntagm =0;
							SyllableElement.PosInPhrase =0;
							SyllableElement.Stress = 0;
							SyllableArray.Add(SyllableElement);
						}
						csMid = csPhrase.Mid(nSyntagmBegPos, nPhraseLen-nSyntagmBegPos);
						csSyntagm = csMid;
						csMid.TrimLeft();
						csMid.TrimRight();
						///////////////////////////////////
						// calculate number of syllable in a syntagm based on ' ' and '-'
						nNumOfSpace = csMid.Remove(' ');
						nNumOfDash	= csMid.Remove('-');
						nSyntagmLenInSyl = nNumOfSpace + nNumOfDash +1;
						nSylPosInSyntagm =0;
						///////////////////////////////////
						nWordBegPos =0;
						nSyntagmLen = csSyntagm.GetLength();
						while(nWordBegPos + 1 < nSyntagmLen)
						{
							nWordEndPos = csSyntagm.Find(' ',nWordBegPos);
							if(nWordEndPos == -1)
							{
								if(nSyntagmLen -nWordBegPos ==0) break;
								////////////////////////////////////////////////////
								// Extract the word from a syntagm.
								////////////////////////////////////////////////////
								csMid = csSyntagm.Mid(nWordBegPos, nSyntagmLen-nWordBegPos);
								csWord = csMid;
								///////////////////////////////////
								// calculate number of syllable in a word based on '-'
								nNumOfDash	= csMid.Remove('-');
								nWordLenInSyl = nNumOfDash +1;
								nSylPosInWord =0;
								///////////////////////////////////
								nSyllableBegPos =0;
								nWordLen = csWord.GetLength();
								while(nSyllableBegPos + 1 <= nWordLen)
								{
									nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
									if(nSyllableEndPos == -1)
									{
										if(nWordLen -nSyllableBegPos ==0) break;
										////////////////////////////////////////////////////
										// Extract the syllable from a word.
										////////////////////////////////////////////////////
										csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
										csSyllable = csMid;
										csSyllable.Remove('-');
										if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
										else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
										if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
										else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
										if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
										else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
										
										nStressPos = csSyllable.Find('\'',0);
										if(nStressPos == csSyllable.GetLength()-1) 
										{
											csSyllable.Remove('\'');
											SyllableElement.Stress = 1;
										}
										else SyllableElement.Stress = 0;
										
										SyllableElement.cUnitName = csSyllable;
										SyllableArray.Add(SyllableElement);
										nSylPosInWord ++; 
										nSylPosInSyntagm++;
										nSylPosInPhrase++;
										//SylArray.Add(csSyllable);
										break;
									}
									csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
									csSyllable = csMid;
									csSyllable.Remove('-');
									csSyllable.Remove(' ');
									
									if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
									else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
									if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
									else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
									if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
									else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
																		
									nStressPos = csSyllable.Find('\'',0);
									if(nStressPos == csSyllable.GetLength()-1) 
									{
										csSyllable.Remove('\'');
										SyllableElement.Stress = 1;
									}
									else SyllableElement.Stress = 0;
									
									SyllableElement.cUnitName = csSyllable;
									SyllableArray.Add(SyllableElement);
									nSylPosInWord ++; 
									nSylPosInSyntagm++;
									nSylPosInPhrase++;
									
									//SylArray.Add(csSyllable);						
									nSyllableBegPos = nSyllableEndPos +1;								
								}
								break;
							}//		if(nWordEndPos == -1)
							////////////////////////////////////////////////////
							// Extract the word from a syntagm.
							////////////////////////////////////////////////////
							csMid = csSyntagm.Mid(nWordBegPos, nWordEndPos-nWordBegPos);
							csWord = csMid;
							///////////////////////////////////
							// calculate number of syllable in a word based on '-'
							nNumOfDash	= csMid.Remove('-');
							nWordLenInSyl = nNumOfDash +1;
							nSylPosInWord =0;
							///////////////////////////////////
							nSyllableBegPos =0;
							nWordLen = csWord.GetLength();
							while(nSyllableBegPos + 1 <= nWordLen)
							{
								nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
								if(nSyllableEndPos == -1)
								{
									if(nWordLen -nSyllableBegPos ==0) break;
									////////////////////////////////////////////////////
									// Extract the syllable from a word.
									////////////////////////////////////////////////////
									csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
									csSyllable = csMid;
									csSyllable.Remove('-');
									csSyllable.Remove(' ');

									if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
									else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
									if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
									else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
									if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
									else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
									
									nStressPos = csSyllable.Find('\'',0);
									if(nStressPos == csSyllable.GetLength()-1) 
									{
										csSyllable.Remove('\'');
										SyllableElement.Stress = 1;
									}
									else SyllableElement.Stress = 0;
									
									SyllableElement.cUnitName = csSyllable;
									SyllableArray.Add(SyllableElement);
									nSylPosInWord ++; 
									nSylPosInSyntagm++;
									nSylPosInPhrase++;

									//SylArray.Add(csSyllable);
									break;
								}
								csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');
								csSyllable.Remove(' ');

								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;
								
								SyllableElement.cUnitName = csSyllable;
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								//SylArray.Add(csSyllable);						
								nSyllableBegPos = nSyllableEndPos +1;								
							}
							nWordBegPos = nWordEndPos +1;
						}//	while(nWordBegPos + 1 < nSyntagmLen)
						break;
					}//if(nSyntagmEndPos == -1)

					////////////////////////////////////////////////////
					// Extract the syntagm from a phrase.
					////////////////////////////////////////////////////
					if(nSyntagmBegPos > 0)	//SylArray.Add("SIL");
					{
						SyllableElement.cUnitName ="SIL";
						SyllableElement.PosInWord =0;
						SyllableElement.PosInSyntagm =0;
						SyllableElement.PosInPhrase =0;
						SyllableElement.Stress = 0;
						SyllableArray.Add(SyllableElement);
					}
					csMid = csPhrase.Mid(nSyntagmBegPos, nSyntagmEndPos-nSyntagmBegPos);
					csSyntagm = csMid;
					csMid.TrimLeft();
					csMid.TrimRight();
					///////////////////////////////////
					// calculate number of syllable in a syntagm based on ' ' and '-'
					nNumOfSpace = csMid.Remove(' ');
					nNumOfDash	= csMid.Remove('-');
					nSyntagmLenInSyl = nNumOfSpace + nNumOfDash +1;
					nSylPosInSyntagm =0;
					///////////////////////////////////
					nWordBegPos =0;
					nSyntagmLen = csSyntagm.GetLength();
					while(nWordBegPos + 1 < nSyntagmLen)
					{
						nWordEndPos = csSyntagm.Find(' ',nWordBegPos);
						if(nWordEndPos == -1)
						{
							if(nSyntagmLen -nWordBegPos ==0) break;
							////////////////////////////////////////////////////
							// Extract the word from a syntagm.
							////////////////////////////////////////////////////
							csMid = csSyntagm.Mid(nWordBegPos, nSyntagmLen-nWordBegPos);
							csWord = csMid;
							///////////////////////////////////
							// calculate number of syllable in a word based on '-'
							nNumOfDash	= csMid.Remove('-');
							nWordLenInSyl = nNumOfDash +1;
							nSylPosInWord =0;
							///////////////////////////////////
							nSyllableBegPos =0;
							nWordLen = csWord.GetLength();
							while(nSyllableBegPos + 1 <= nWordLen)
							{
								nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
								if(nSyllableEndPos == -1)
								{
									if(nWordLen -nSyllableBegPos ==0) break;
									////////////////////////////////////////////////////
									// Extract the syllable from a word.
									////////////////////////////////////////////////////
									csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
									csSyllable = csMid;
									csSyllable.Remove('-');
									csSyllable.Remove(' ');

									if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
									else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
									if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
									else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
									if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
									else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								

									nStressPos = csSyllable.Find('\'',0);
									if(nStressPos == csSyllable.GetLength()-1) 
									{
										csSyllable.Remove('\'');
										SyllableElement.Stress = 1;
									}
									else SyllableElement.Stress = 0;
									
									SyllableElement.cUnitName = csSyllable;	
									SyllableArray.Add(SyllableElement);

									nSylPosInWord ++; 
									nSylPosInSyntagm++;
									nSylPosInPhrase++;
									//SylArray.Add(csSyllable);
									break;
								}
								csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');
								csSyllable.Remove(' ');
								
								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;
									
								SyllableElement.cUnitName = csSyllable;
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								//SylArray.Add(csSyllable);						
								nSyllableBegPos = nSyllableEndPos +1;								
							}
							break;
						}
						////////////////////////////////////////////////////
						// Extract the word from a syntagm.
						////////////////////////////////////////////////////
						csMid = csSyntagm.Mid(nWordBegPos, nWordEndPos-nWordBegPos);
						csWord = csMid;
						///////////////////////////////////
						// calculate number of syllable in a word based on '-'
						nNumOfDash	= csMid.Remove('-');
						nWordLenInSyl = nNumOfDash +1;
						nSylPosInWord =0;
						///////////////////////////////////
						nSyllableBegPos =0;
						nWordLen = csWord.GetLength();
						while(nSyllableBegPos + 1 <= nWordLen)
						{
							nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
							if(nSyllableEndPos == -1)
							{
								if(nWordLen -nSyllableBegPos ==0) break;
								////////////////////////////////////////////////////
								// Extract the syllable from a word.
								////////////////////////////////////////////////////
								csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');
								csSyllable.Remove(' ');
								
								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;
									
								SyllableElement.cUnitName = csSyllable;
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								
								//SylArray.Add(csSyllable);
								break;
							}
							csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
							csSyllable = csMid;
							csSyllable.Remove('-');
							csSyllable.Remove(' ');
							
							if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
							else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
							if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
							else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
							if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
							else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
							
							nStressPos = csSyllable.Find('\'',0);
							if(nStressPos == csSyllable.GetLength()-1) 
							{
								csSyllable.Remove('\'');
								SyllableElement.Stress = 1;
							}
							else SyllableElement.Stress = 0;
							
							SyllableElement.cUnitName = csSyllable;
							SyllableArray.Add(SyllableElement);
							nSylPosInWord ++; 
							nSylPosInSyntagm++;
							nSylPosInPhrase++;
							//SylArray.Add(csSyllable);						
							nSyllableBegPos = nSyllableEndPos +1;								
						}
						nWordBegPos = nWordEndPos +1;
					}//	while(nWordBegPos + 1 < nSyntagmLen)
					nSyntagmBegPos = nSyntagmEndPos +1;
				}//while(nSyntagmBegPos + 1 <nPhraseLen)
				////////////////////////////////////////////////////
				break;
			}//		if(nPhraseEndPos == -1)
			////////////////////////////////////////////////////
			// Extract the phrase of a paragraph.
			////////////////////////////////////////////////////
			//cout <<"hehe"<<endl;//thaodv 280211 - goi toi cau lenh nay ma khong goi cau lenh tai dong 192 --> nPhraseEndPos != -1
			if(nPhraseBegPos > 0)	//SylArray.Add("SILS");
			{
				SyllableElement.cUnitName ="SILS";
				SyllableElement.PosInWord =0;
				SyllableElement.PosInSyntagm =0;
				SyllableElement.PosInPhrase =0;
				SyllableElement.Stress = 0;
				SyllableArray.Add(SyllableElement);
			}
			csMid= cs.Mid(nPhraseBegPos, nPhraseEndPos - nPhraseBegPos);
			csMid.Replace('\t',' ');
			for(;;)
			{
				int nIsDoubleSpace;
				nIsDoubleSpace = csMid.Replace("  "," ");
				if (nIsDoubleSpace == 0) break;
			}
			csPhrase = csMid;// tach ra tung cau, luu vao csMid --> xu ly dau tab, khoang trang --> luu vao csPhrase
			//cout <<"this is csPhrase: "<< csPhrase <<endl;
			//WriteToTextFile(csPhrase);
			csMid.TrimLeft();
			csMid.TrimRight();
			///////////////////////////////////
			// calculate number of syllable in phrase base on ' ' and '-'
			//tinh toan so luong am tiet trong cau dua tren dau ' ' va '-'
			nNumOfSpace = csMid.Remove(' ');// tra ve so luong dau cach trong cau thaodv 280211
			nNumOfDash	= csMid.Remove('-');
			nPhraseLenInSyl = nNumOfSpace + nNumOfDash +1;
			nSylPosInPhrase =0;
			///////////////////////////////////
			nSyntagmBegPos =0;//nSyntagmBegPos luu vi tri dau phay, la ket thuc cua mot cum tu
			nPhraseLen = csPhrase.GetLength();  // them cac ki tu \0 o cuoi moi String nen GetLength tra ve kq > 2
			///////////// thaodv 280211
			CString tmpstr;
			tmpstr.Format("%d",nPhraseLen);
			//WriteToTextFile(tmpstr);// in ra do dai cua cau.
			//////////// thaodv 280211
			while(nSyntagmBegPos + 1 <nPhraseLen) // khi ma chua duyet het cau - day la vong lap chinh. thaodv 280211
			{
				nSyntagmEndPos = csPhrase.Find(',',nSyntagmBegPos);
				// tim dau phay trong cau tu vi tri nSyntagmBegPos, luu vi tri dau phay vao nSyntagmEndPos. thaodv 280211
				if(nSyntagmEndPos == -1) //xu ly neu khong co dau ','; end in line 856
				{
				// csPhrase = tôi là một độc giả thường xuyên của chuyên mục tâm sự; thaodv 280211
				
					if(nPhraseLen - nSyntagmBegPos ==0) break; //ket thuc khi dau phay trung voi vi tri cuoi cau.
					////////////////////////////////////////////////////
					// Extract the syntagm from a phrase.
					////////////////////////////////////////////////////
					if(nSyntagmBegPos > 0)	//SylArray.Add("SIL");
					{
						SyllableElement.cUnitName ="SIL";
						SyllableElement.PosInWord =0;
						SyllableElement.PosInSyntagm =0;
						SyllableElement.PosInPhrase =0;
						SyllableElement.Stress = 0;
						SyllableArray.Add(SyllableElement);
					}
					csMid = csPhrase.Mid(nSyntagmBegPos, nPhraseLen-nSyntagmBegPos);
					// lay toan bo cau trong csPhrase do nSyntagmBegPos = 0;
					csSyntagm = csMid;
					csMid.TrimLeft();
					csMid.TrimRight();
					///////////////////////////////////
					// calculate number of syllable in a syntagm based on ' ' and '-'
					nNumOfSpace = csMid.Remove(' ');
					nNumOfDash	= csMid.Remove('-');
					nSyntagmLenInSyl = nNumOfSpace + nNumOfDash +1;
					nSylPosInSyntagm =0;
					///////////////////////////////////
					nWordBegPos =0;
					nSyntagmLen = csSyntagm.GetLength();
					while(nWordBegPos + 1 < nSyntagmLen)
					// tach ra tung am tiet dua vao ' ' ; thaodv 280211
					{
						nWordEndPos = csSyntagm.Find(' ',nWordBegPos);
						if(nWordEndPos == -1)
						{
							if(nSyntagmLen -nWordBegPos ==0) break;
							////////////////////////////////////////////////////
							// Extract the word from a syntagm.
							////////////////////////////////////////////////////
							csMid = csSyntagm.Mid(nWordBegPos, nSyntagmLen-nWordBegPos);
							csWord = csMid;
							///////////////////////////////////
							// calculate number of syllable in a word based on '-'
							nNumOfDash	= csMid.Remove('-');
							nWordLenInSyl = nNumOfDash +1;
							nSylPosInWord =0;
							///////////////////////////////////
							nSyllableBegPos =0;
							nWordLen = csWord.GetLength();
							while(nSyllableBegPos + 1 <= nWordLen)
							{
								nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
								if(nSyllableEndPos == -1)
								{
									if(nWordLen -nSyllableBegPos ==0) break;
									////////////////////////////////////////////////////
									// Extract the syllable from a word.
									////////////////////////////////////////////////////
									csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
									csSyllable = csMid;
									csSyllable.Remove('-');
									csSyllable.Remove(' ');
									
									if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
									else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
									if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
									else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
									if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
									else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
									
									nStressPos = csSyllable.Find('\'',0);
									if(nStressPos == csSyllable.GetLength()-1) 
									{
										csSyllable.Remove('\'');
										SyllableElement.Stress = 1;
									}
									else SyllableElement.Stress = 0;
									
									SyllableElement.cUnitName = csSyllable;	
									//WriteToTextFile(csSyllable); //thaodv 280211 - chi thay in ra am tiet cuoi cau
									// csSyllable la am tiet cua doan van ban dau vao. thaodv 280211
									// UNITINFOFULL SyllableElement: cap nhat thong tin am tiet. thaodv 280211
									SyllableArray.Add(SyllableElement);// them vao mang SyllableArray thaodv 280211
									nSylPosInWord ++; 
									nSylPosInSyntagm++;
									nSylPosInPhrase++;
									//SylArray.Add(csSyllable);
									break;
								}
								csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');

								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;

								SyllableElement.cUnitName = csSyllable;	
								//WriteToTextFile(csSyllable);//ko thay in ra am tiet nao thaodv 280211
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								//SylArray.Add(csSyllable);						
								nSyllableBegPos = nSyllableEndPos +1;								
							}
							break;
						}//		if(nWordEndPos == -1)
						////////////////////////////////////////////////////
						// Extract the word from a syntagm.
						////////////////////////////////////////////////////
						csMid = csSyntagm.Mid(nWordBegPos, nWordEndPos-nWordBegPos);
						csWord = csMid;
						///////////////////////////////////
						// calculate number of syllable in a word based on '-'
						nNumOfDash	= csMid.Remove('-');
						nWordLenInSyl = nNumOfDash +1;
						nSylPosInWord =0;
						///////////////////////////////////
						nSyllableBegPos =0;
						nWordLen = csWord.GetLength();
						while(nSyllableBegPos + 1 <= nWordLen)
						{
							nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
							if(nSyllableEndPos == -1)
							{
								if(nWordLen -nSyllableBegPos ==0) break;
								////////////////////////////////////////////////////
								// Extract the syllable from a word.
								////////////////////////////////////////////////////
								csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');
								csSyllable.Remove(' ');

								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
								
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;
								
								SyllableElement.cUnitName = csSyllable;
								//WriteToTextFile(csSyllable); //thaodv 280211 - in ra tat ca cac am tiet tu dau cau cho toi vi tri gan cuoi cau / tru am tiet cuoi cung
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								//SylArray.Add(csSyllable);
								break;
							}
							csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
							csSyllable = csMid;
							csSyllable.Remove('-');
							csSyllable.Remove(' ');
							
							if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
							else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
							if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
							else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
							if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
							else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
							
							nStressPos = csSyllable.Find('\'',0);
							if(nStressPos == csSyllable.GetLength()-1) 
							{
								csSyllable.Remove('\'');
								SyllableElement.Stress = 1;
							}
							else SyllableElement.Stress = 0;
							
							SyllableElement.cUnitName = csSyllable;
							//WriteToTextFile(csSyllable); //thaodv 280211-ko thay in ra gi ca hichic
							SyllableArray.Add(SyllableElement);
							nSylPosInWord ++; 
							nSylPosInSyntagm++;
							nSylPosInPhrase++;
							//SylArray.Add(csSyllable);						
							nSyllableBegPos = nSyllableEndPos +1;								
						}
						nWordBegPos = nWordEndPos +1;
					}//	while(nWordBegPos + 1 < nSyntagmLen)
				//	SylArray.Add("SILS");
					break;
				}//if(nSyntagmEndPos == -1)
				////////////////////////////////////////////////////
				// Extract the syntagm from a phrase.
				////////////////////////////////////////////////////
				if(nSyntagmBegPos > 0)	//SylArray.Add("SIL");
				{
					SyllableElement.cUnitName ="SIL";
					SyllableElement.PosInWord =0;
					SyllableElement.PosInSyntagm =0;
					SyllableElement.PosInPhrase =0;
					SyllableElement.Stress = 0;
					SyllableArray.Add(SyllableElement);
				}
				csMid = csPhrase.Mid(nSyntagmBegPos, nSyntagmEndPos-nSyntagmBegPos);
				csSyntagm = csMid;
				csMid.TrimLeft();
				csMid.TrimRight();
				///////////////////////////////////
				// calculate number of syllable in a syntagm based on ' ' and '-'
				nNumOfSpace = csMid.Remove(' ');
				nNumOfDash	= csMid.Remove('-');
				nSyntagmLenInSyl = nNumOfSpace + nNumOfDash +1;
				nSylPosInSyntagm =0;
						///////////////////////////////////
				nWordBegPos =0;
				nSyntagmLen = csSyntagm.GetLength();
				while(nWordBegPos + 1 < nSyntagmLen)
				{
					nWordEndPos = csSyntagm.Find(' ',nWordBegPos);
					if(nWordEndPos == -1)
					{
						if(nSyntagmLen -nWordBegPos ==0) break;
						////////////////////////////////////////////////////
						// Extract the word from a syntagm.
						////////////////////////////////////////////////////
						csMid = csSyntagm.Mid(nWordBegPos, nSyntagmLen-nWordBegPos);
						csWord = csMid;
						///////////////////////////////////
						// calculate number of syllable in a word based on '-'
						nNumOfDash	= csMid.Remove('-');
						nWordLenInSyl = nNumOfDash +1;
						nSylPosInWord =0;
						///////////////////////////////////
						nSyllableBegPos =0;
						nWordLen = csWord.GetLength();
						while(nSyllableBegPos + 1 <= nWordLen)
						{
							nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
							if(nSyllableEndPos == -1)
							{
								if(nWordLen -nSyllableBegPos ==0) break;
								////////////////////////////////////////////////////
								// Extract the syllable from a word.
								////////////////////////////////////////////////////
								csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
								csSyllable = csMid;
								csSyllable.Remove('-');
								csSyllable.Remove(' ');
								
								if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
								else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
								if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
								else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
								if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
								else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
							
								nStressPos = csSyllable.Find('\'',0);
								if(nStressPos == csSyllable.GetLength()-1) 
								{
									csSyllable.Remove('\'');
									SyllableElement.Stress = 1;
								}
								else SyllableElement.Stress = 0;
							
								SyllableElement.cUnitName = csSyllable;
								//WriteToTextFile(csSyllable);//thaodv 280211 in ra am tiet dung truoc dau ','
								SyllableArray.Add(SyllableElement);
								nSylPosInWord ++; 
								nSylPosInSyntagm++;
								nSylPosInPhrase++;
								//SylArray.Add(csSyllable);
								break;
							}
							csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
							csSyllable = csMid;
							csSyllable.Remove('-');
							csSyllable.Remove(' ');

							if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
							else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
							if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
							else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
							if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
							else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
							
							nStressPos = csSyllable.Find('\'',0);
							if(nStressPos == csSyllable.GetLength()-1) 
							{
								csSyllable.Remove('\'');
								SyllableElement.Stress = 1;
							}
							
							SyllableElement.cUnitName = csSyllable;
							SyllableArray.Add(SyllableElement);
							//WriteToTextFile(csSyllable);//thaodv 280211-ko thay in ra gi ca
							nSylPosInWord ++; 
							nSylPosInSyntagm++;
							nSylPosInPhrase++;
							//SylArray.Add(csSyllable);						
							nSyllableBegPos = nSyllableEndPos +1;								
						}
						break;
					}
					////////////////////////////////////////////////////
					// Extract the word from a syntagm.
					////////////////////////////////////////////////////
					csMid = csSyntagm.Mid(nWordBegPos, nWordEndPos-nWordBegPos);
					csWord = csMid;
					///////////////////////////////////
					// calculate number of syllable in a word based on '-'
					nNumOfDash	= csMid.Remove('-');
					nWordLenInSyl = nNumOfDash +1;
					nSylPosInWord =0;
					///////////////////////////////////
					nSyllableBegPos =0;
					nWordLen = csWord.GetLength();
					while(nSyllableBegPos + 1 <= nWordLen)
					{
						nSyllableEndPos = csWord.Find('-',nSyllableBegPos);
						if(nSyllableEndPos == -1)
						{
							if(nWordLen -nSyllableBegPos ==0) break;
							////////////////////////////////////////////////////
							// Extract the syllable from a word.
							////////////////////////////////////////////////////
							csMid = csWord.Mid(nSyllableBegPos, nWordLen-nSyllableBegPos);
							csSyllable = csMid;
							csSyllable.Remove('-');
							csSyllable.Remove(' ');
							
							if((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
							else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
							if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
							else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
							if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
							else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
							
							nStressPos = csSyllable.Find('\'',0);
							if(nStressPos == csSyllable.GetLength()-1) 
							{
								csSyllable.Remove('\'');
								SyllableElement.Stress = 1;
							}
							else SyllableElement.Stress = 0;
							
							SyllableElement.cUnitName = csSyllable;
							//WriteToTextFile(csSyllable);//thaodv 280211- in ra cac am tiet dung truoc am tiet lien truoc dau phay cua cac clause ko phai clause cuoi cung
							SyllableArray.Add(SyllableElement);
							nSylPosInWord ++; 
							nSylPosInSyntagm++;
							nSylPosInPhrase++;
							//SylArray.Add(csSyllable);
							break;
						}
						csMid = csWord.Mid(nSyllableBegPos, nSyllableEndPos-nSyllableBegPos);
						csSyllable = csMid;
						csSyllable.Remove('-');
						csSyllable.Remove(' ');
						
						if(((nSylPosInWord == (nWordLenInSyl-1))&&(nWordLenInSyl>1))&&(nWordLenInSyl>1)) SyllableElement.PosInWord = 1;
						else SyllableElement.PosInWord = float(nSylPosInWord)/nWordLenInSyl;
						if(nSylPosInSyntagm == (nSyntagmLenInSyl-1)) SyllableElement.PosInSyntagm = 1;
						else SyllableElement.PosInSyntagm = float(nSylPosInSyntagm)/nSyntagmLenInSyl;
						if(nSylPosInPhrase == (nPhraseLenInSyl-1)) SyllableElement.PosInPhrase = 1;
						else SyllableElement.PosInPhrase = float(nSylPosInPhrase)/nPhraseLenInSyl;
					
						nStressPos = csSyllable.Find('\'',0);
						if(nStressPos == csSyllable.GetLength()-1) 
						{
							csSyllable.Remove('\'');
							SyllableElement.Stress = 1;
						}
						else SyllableElement.Stress = 0;
						
						SyllableElement.cUnitName = csSyllable;
						//WriteToTextFile(csSyllable); //thaodv 280211-ko thay in ra gi ca
						SyllableArray.Add(SyllableElement);
						nSylPosInWord ++; 
						nSylPosInSyntagm++;
						nSylPosInPhrase++;
						//SylArray.Add(csSyllable);						
						nSyllableBegPos = nSyllableEndPos +1;								
					}
					nWordBegPos = nWordEndPos +1;
				}//	while(nWordBegPos + 1 < nSyntagmLen)
				nSyntagmBegPos = nSyntagmEndPos +1;
			}//while(nSyntagmBegPos + 1 <nPhraseLen)
			////////////////////////////////////////////////////
			nPhraseBegPos = nPhraseEndPos +1;			

		/*}// End of while( nPhraseBegPos + 1 < nLen )*/
		if(nPhraseBegPos + 1>= nLen) // khi da duyet het cau thi them SILP vao ben trai cau thaodv 010311
		{
			SyllableElement.cUnitName ="SILP";
			SyllableElement.PosInWord =0;
			SyllableElement.PosInSyntagm =0;
			SyllableElement.PosInPhrase =0;
			SyllableElement.Stress = 0;

			SyllableArray.Add(SyllableElement);
		}
		
		GetSylArrayPosInTextDB(SyllableArray);// luc nay da duyet het cau. thaodv 170311
		int dwSize = SyllableArray.GetSize();//thaodv-lay kich thuoc cua mang cac am tiet.
		
		for(j=0; j<dwSize;j++)	
		{
			//SyllableAnalysis(SyllableArray.ElementAt(j));
			//if( SyllableAnalysis(SyllableArray.ElementAt(j))==TRUE) // Dung thu ham moi
			if(SyllableAnalysis(SyllableArray.ElementAt(j).cUnitName,SyllableArray.ElementAt(j))==TRUE)
			{
				if(SyllableArray.ElementAt(j).PosInSyntagm ==1) SyllableArray.ElementAt(j).Stress =1;
				// neu vi tri cua am tiet o dau cau thi trong am = 1; thaodv 010311
				//else if(SyllableArray.ElementAt(j).Stress !=1) SyllableArray.ElementAt(j).Stress = 0;
				
				//////////////////////////////////////////////////////////////////////////////////////////////////////////
				SyllableElement = SyllableArray.GetAt(j);
				for(i=0; i<4;i++) 
				{
					if(SyllableElement.csSound[i]=="NUL") SyllableElement.csSound[i].Empty();
					for(int k=0; k<13; k++)
					{
					// chuyen doi ki hieu am vi theo nhu dinh nghia tai dong 112, 113. thaodv 010311
						if(SyllableElement.csSound[i] == csPhoneme[k]) 
						{
							SyllableElement.csSound[i] = csPhonemeConverted[k];
							SyllableArray.ElementAt(j).csSound[i] = csPhonemeConverted[k];
							break;
						}
					}
				}
					
				bUnitType =CPsola::bSettingUnitType;

				switch (bUnitType)
				{
					
					case 0:// AUnit
						for(i=0; i<4;i++) SyllableArray.ElementAt(j).csSubUnit[i] = SyllableElement.csSound[i];
						SyllableArray.ElementAt(j).bNumOfSubUnit = 4;
						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						break;

					case 1:// AUnit
						SyllableArray.ElementAt(j).bNumOfSubUnit = 4;
						SyllableArray.ElementAt(j).csSubUnit[0] = '_' + SyllableElement.csSound[0];
						if(SyllableArray.ElementAt(j).csSubUnit[0] == "_")
						{
							SyllableArray.ElementAt(j).bNumOfSubUnit --;
							SyllableArray.ElementAt(j).csSubUnit[0] = '_' + SyllableElement.csSound[1]+SyllableElement.csSound[2];
							SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[2]+SyllableElement.csSound[3];
							SyllableArray.ElementAt(j).csSubUnit[2] = SyllableElement.csSound[3]+ '_';
							if(SyllableArray.ElementAt(j).csSubUnit[2] =="_")
							{
								SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[2]+'_';
								SyllableArray.ElementAt(j).csSubUnit[2].Empty();
								SyllableArray.ElementAt(j).bNumOfSubUnit--;
							}
						}
						else
						{
							SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[0]+SyllableElement.csSound[1]+SyllableElement.csSound[2];
							SyllableArray.ElementAt(j).csSubUnit[2] = SyllableElement.csSound[2]+SyllableElement.csSound[3];
							SyllableArray.ElementAt(j).csSubUnit[3] = SyllableElement.csSound[3]+ '_';
							if(SyllableArray.ElementAt(j).csSubUnit[3] =="_")
							{
								SyllableArray.ElementAt(j).csSubUnit[2] = SyllableElement.csSound[2]+'_';
								SyllableArray.ElementAt(j).csSubUnit[3].Empty();
								SyllableArray.ElementAt(j).bNumOfSubUnit--;
							}
						}

						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						break;
					case 2:// Demisyllable
						SyllableArray.ElementAt(j).csSubUnit[0] = '_' + SyllableElement.csSound[0]+SyllableElement.csSound[1]+SyllableElement.csSound[2];
						SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[2]+SyllableElement.csSound[3] +'_';
						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						SyllableArray.ElementAt(j).bNumOfSubUnit = 2;
						break;
					case 3:// Initial - Final Part
						SyllableArray.ElementAt(j).csSubUnit[0] = '_' + SyllableElement.csSound[0];
						SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[2] + SyllableElement.csSound[2]+SyllableElement.csSound[3];
						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						SyllableArray.ElementAt(j).bNumOfSubUnit = 2;
						break;
					case 4:// Syllble 
						SyllableArray.ElementAt(j).csSubUnit[0] = SyllableElement.csSound[0]+SyllableElement.csSound[1]+SyllableElement.csSound[2]+SyllableElement.csSound[3];
						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						SyllableArray.ElementAt(j).bNumOfSound = 1;
						break;
					case 5:// Combination - At this time Combination = Demi-syllable. 23/12/2006
						SyllableArray.ElementAt(j).csSubUnit[0] = '_' + SyllableElement.csSound[0]+SyllableElement.csSound[1]+SyllableElement.csSound[2];
						SyllableArray.ElementAt(j).csSubUnit[1] = SyllableElement.csSound[2]+SyllableElement.csSound[3] +'_';
						SyllableArray.ElementAt(j).bUnitType = bUnitType;
						SyllableArray.ElementAt(j).bNumOfSubUnit = 2;
						break;
				}

			//////////////////////////////////////////////////////////////////////////////////////////////////////////
			} //end If
			else
			{
				// neu khong phan tich duoc am tiet thi loai bo phan tu dang phan tich khoi SyllableArray thaodv 010311
				SyllableArray.RemoveAt(j,1);
				dwSize--;
				j--;
			}
		}// End for
		
		dwBegin = dwEnd =0;
		///////////////////////////////////////////////////
		// Analysing the context of the syllable	     //
		///////////////////////////////////////////////////

		for(i=0; i<dwSize; i++)
		{
			if((dwBegin == dwEnd)&&(dwEnd < dwSize -1))
			{
				//int j;
				j=1;
				for(;;)
				{
					csSyllable = SyllableArray.GetAt(i+j).cUnitName;
					if((csSyllable=="SIL")||(csSyllable=="SILS")||(csSyllable=="SILP")||(dwEnd == (dwSize - 1))||((i+j)==(dwSize-1)))
					{
						dwEnd = i+j;
						nPhraseLenInSyl = dwEnd - dwBegin-1;
						break;
					}
					j++;
				}
			}
					
			if(i==0)
			{
				if((SyllableArray.GetAt(i).cUnitName=="SILP")||(SyllableArray.GetAt(i).cUnitName=="SILS"))
				{
					SyllableArray.ElementAt(i).cLeftUnitName = "NULL";
					dwBegin = i;
				}
				else
				{
					SyllableArray.ElementAt(i).cLeftUnitName = "SILS";
					dwBegin = -1;
				}
				SyllableArray.ElementAt(i).csLeftPhone = "NUL";
				SyllableArray.ElementAt(i).csLeftPhoneType = "NUL";
				SyllableArray.ElementAt(i).bLeftTone = 0;
			}
			else 
			{
				csSyllable = SyllableArray.GetAt(i).cUnitName;
				SyllableArray.ElementAt(i).cLeftUnitName = SyllableArray.GetAt(i-1).cUnitName;
				SyllableArray.ElementAt(i).bLeftTone	 = SyllableArray.GetAt(i-1).bTone;
						
				if((SyllableArray.GetAt(i-1).cUnitName=="SILP")||(SyllableArray.GetAt(i-1).cUnitName=="SILS")||(SyllableArray.GetAt(i-1).cUnitName=="SIL"))
				{
					SyllableArray.ElementAt(i).csLeftPhone = "NUL";
					SyllableArray.ElementAt(i).csLeftPhoneType = "NUL";
				}
				else 
					for(int nSound =3; nSound >=0; nSound--)
					if(SyllableArray.GetAt(i-1).csSound[nSound].Compare("NUL")) 
					{
						SyllableArray.ElementAt(i).csLeftPhone = SyllableArray.GetAt(i-1).csSound[nSound];
						SyllableArray.ElementAt(i).csLeftPhoneType = SyllableArray.GetAt(i-1).csSoundType[nSound];
						break;
					}
									
				if((csSyllable =="SIL")||(csSyllable =="SILS")||(csSyllable =="SILP")) dwBegin = dwEnd;
										
			}
			if(i < dwSize -1) 
			{
				SyllableArray.ElementAt(i).cRightUnitName = SyllableArray.GetAt(i+1).cUnitName;
				SyllableArray.ElementAt(i).bRightTone = SyllableArray.GetAt(i+1).bTone;
				
				if((SyllableArray.GetAt(i+1).cUnitName=="SILP")||(SyllableArray.GetAt(i+1).cUnitName=="SILS")||(SyllableArray.GetAt(i+1).cUnitName=="SIL"))
				{
					SyllableArray.ElementAt(i).csRightPhone = "NUL";
					SyllableArray.ElementAt(i).csRightPhoneType = "NUL";
				}
				else
					for(int nSound =0; nSound <=3; nSound++)
					if(SyllableArray.GetAt(i+1).csSound[nSound].Compare("NUL")) 
					{
						SyllableArray.ElementAt(i).csRightPhone = SyllableArray.GetAt(i+1).csSound[nSound];
						SyllableArray.ElementAt(i).csRightPhoneType = SyllableArray.GetAt(i+1).csSoundType[nSound];
						break;
					}
			}
			else 
			{
				SyllableArray.ElementAt(i).cRightUnitName = "NULL";
				SyllableArray.ElementAt(i).bRightTone = 0;
				SyllableArray.ElementAt(i).csRightPhone = "NUL";
				SyllableArray.ElementAt(i).csRightPhoneType = "NUL";
			}
					
			SyllableArray.ElementAt(i).wIndex = i - dwBegin;
			SyllableArray.ElementAt(i).nPhraseLen = nPhraseLenInSyl;
					
		}

		///////////////////////////////////////////////////
		// End of analysing the context of the syllable	 //
		///////////////////////////////////////////////////
		float Length;
		int node;
		for(j=0; j<dwSize;j++)	
		{
			SyllableElement = SyllableArray.GetAt(j);
			
			if((SyllableElement.cUnitName == "SILP")||(SyllableElement.cUnitName =="SILS"))
				SyllableArray.ElementAt(j).dwUnitLen = 6400;
			else
			{
				if(SyllableElement.cUnitName == "SIL")
				SyllableArray.ElementAt(j).dwUnitLen = 3000;
				else
				{
					SyllableArray.ElementAt(j).PosInPhrase = SyllableArray.ElementAt(j).PosInSyntagm;
					DurationModel(SyllableElement, Length, node);//goi toi ham mo hinh hoa truong do thaodv 010311
					SyllableArray.ElementAt(j).dwUnitLen = int(Length)*(1/CPsola::fSpeakingRate)*fSpeakingRate;//*1.1f;//*1.2f;
					SyllableArray.ElementAt(j).dwEnergy	 = EnergyModel(SyllableElement);
					//goi toi ham mo hinh nang luong thaodv 010311
				}
			}
		}
		//GetSylArrayPosInTextDB(SyllableArray); // luc nay cac am tiet da duoc tach dau. phai goi ham nay som hon
		F0ContourGeneration(SyllableArray);
		//
		
		
		//Empty();
		for(j=0; j<dwSize;j++)
		{
			SyllableElement = SyllableArray.GetAt(j);
			csTemp.Empty();
			////////////////////////////////////////////////
			
			SYLLABLESTRUCT *psst;
			psst = new SYLLABLESTRUCT;
			if(!ParseSylInfo(SyllableElement,psst))
			{
				Empty();
				delete psst;
				return FALSE;
			}
			if((BTypeOfPhrase == 1)&&(SyllableElement.PosInPhrase ==1))
			{
				float fDelta, fStep;
				fDelta = 0.1f;
				fStep = fDelta/ SyllableElement.numOfF0;
				for(int nF0Pos = 0; nF0Pos < SyllableElement.numOfF0; nF0Pos++)
					psst->nFo[nF0Pos] = int(psst->nFo[nF0Pos]*(1+ float(fStep*nF0Pos)));
				psst->nEnergy = int(SyllableElement.dwEnergy*1.25f);
				if(psst->nEnergy >32) psst->nEnergy =32;

			}
			m_pdwSyl.Add((DWORD)psst);
			////////////////////////////////////////////////
			//cout << "psst: " <<psst << endl; //thaodv 240211
			//cout << "m_pdwSyl: " <<m_pdwSyl.GetAt(1) << endl; //thaodv 240211
			//Sua lai de ghi ra file day du thong tin cung cap cho qua trinh tim kiem va ghep noi.19/3/2009

			if((SyllableElement.cUnitName !="SILP")&&(SyllableElement.cUnitName !="SILS")&&(SyllableElement.cUnitName !="SIL"))
			{				
				csTemp.Format("%d ", SyllableElement.bNumOfSubUnit);//Them vao so luong cua SubUnit
				csTemp1 = csTemp;
				csTemp.Empty();
				// Them vao ten cac don vi am
				for(i=0; i< SyllableElement.bNumOfSubUnit; i++)
				csTemp = csTemp + SyllableElement.csSubUnit[i]+ ' ';
							
				csTemp1 += csTemp;
				csTemp.Empty();
				csTemp.Format("%d ", SyllableElement.dwUnitLen*BYTESPERSAMPLE);//Them vao *BYTESPERSAMPLE
				csTemp1 = csTemp1 + csTemp;
				csTemp.Empty();
				
				csTemp.Format("%d ", SyllableElement.bTone);// Them vao bTone
				csTemp1 += csTemp;
				csTemp.Empty();
				csTemp.Format("%d ", (int)SyllableElement.dwEnergy);// Them vao gia tri nang luong
				csTemp1 += csTemp;
				csTemp.Empty();
				csTemp.Format("%d ", SyllableElement.numOfF0);// Them vao gia tri cua 
				csTemp1 += csTemp;
				csTemp.Empty();
			//	for(i=0;i< SyllableElement.bNumOfSubUnit; i++)// Them vao gia tri cua mang bUnitIndex[]
			//	{
			//	  csTemp.Format("%d ",1);
			//	  csTemp1 += csTemp;
			//	  csTemp.Empty();
			//	
			//	}
				csF0.Empty();

				for(i=0; i< SyllableElement.numOfF0; i++)// Chinh sua lai viec ghi ra mang F0
				{
					int nF0Value;
					//nF0Value = int(CPsola::nF0_Begin*SyllableElement.fF0[i]);
					nF0Value = int(SyllableElement.fF0[i] * CPsola::nF0_Begin *fRegister);
					if(nF0Value < int(0.5f* CPsola::nF0_Begin)) nF0Value = int(0.55f* CPsola::nF0_Begin);
					csTemp.Format("%d", nF0Value);
					if(i!=SyllableElement.numOfF0-1)
						csF0 = csF0 + csTemp + ' ';
					else
						csF0 = csF0 + csTemp; 
					

				}

				csTemp1 = csTemp1 + csF0 + "\n";
			}
			else
			{
				csTemp1.Format("_ %d\n", SyllableElement.dwUnitLen*BYTESPERSAMPLE);
			}

			/*csTemp.Format(" %d\t%s\t%d\t%s\t%s\t%s\t%s\t%4.2f %4.2f %4.2f\t%d\t%d\t%s\t%s\t%d\t%d\t%s\t%s\t%s\t%s\n",j, SyllableElement.cUnitName, SyllableElement.bTone, 
				SyllableElement.csSoundType[0],SyllableElement.csSoundType[1],SyllableElement.csSoundType[2],SyllableElement.csSoundType[3],
				SyllableElement.PosInWord,SyllableElement.PosInSyntagm,SyllableElement.PosInPhrase,SyllableElement.bLeftTone,
				SyllableElement.bRightTone,SyllableElement.csLeftPhoneType,SyllableElement.csRightPhoneType, SyllableElement.dwUnitLen, node,
				SyllableElement.csSubUnit[0], SyllableElement.csSubUnit[1],SyllableElement.csSubUnit[2], SyllableElement.csSubUnit[3]);*/
			csOut = csOut + csTemp1;
		}
		SyllableArray.RemoveAll();

		}// End of while( nPhraseBegPos + 1 < nLen )
	
		
		////////////////////////////////////////////////////////
		// Exporting the prosodic information into file: Analysed Phrase.syn
		/////////////////////////////////////////////////////////////////////
		FILE *fOut;
		if( (fOut = fopen("Analysed Phrase.syn", "wt")) == NULL ) // .syn = synthesis: this file contains all of the prosodic information of the synthetic phrase.
		{
						
			///////////////////////////////////////
			/*		bao loi ra ngoai file debug	 */
			///////////////////////////////////////
			CString strOut;
			strOut = "Can not open this file: Analysed Phrase.syn";
			CPsola::OutputLastError(strOut);
			////////////////////////////////////////
			return FALSE;
		}
		fwrite(csOut,csOut.GetLength(),1,fOut);
		fclose(fOut);

		//////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////
		cs.Empty();
		cs = csOut;
	
	} //if(CPsola::BAutoORHandF0 == TRUE) 

	else // xu ly neu thong tin dau vao khong hop le
	{
		Empty();
		SYLLABLESTRUCT *psst;
		i = -1;
		j = 0;
		cs.Remove('\r');
		nLen = cs.GetLength();
		//CString csMid;
		while( i + 1 < nLen )
		{
			i = cs.Find('\n',j);
			if(i == -1){
				if( nLen - j == 0) break;
				psst = new SYLLABLESTRUCT;
				psst->nNumberFo = 0;
				csMid = cs.Mid(j,nLen - j);
				csMid.Insert(0,' ');
				csMid.Insert(csMid.GetLength(),' ');
				csMid.Replace('\t',' ');
				while(csMid.Replace("  "," "));
				if(*((LPCTSTR)csMid + 1)==';'){
					delete psst;
					break;
				}
				if(csMid.GetLength() < 3){
					delete psst;
					break;
				}
				if(!ParseSylInfo(csMid,psst)){
					Empty();
					delete psst;
					return FALSE;
				}
				m_pdwSyl.Add((DWORD)psst);
				break;
			}
			if( i - j == 0) {
				j = i + 1;
				continue;
			}

			psst = new SYLLABLESTRUCT;
			psst->nNumberFo = 0;
			csMid = cs.Mid(j,i-j);
			csMid.Insert(0,' ');
			csMid.Insert(csMid.GetLength(),' ');
			csMid.Replace('\t',' ');
			while(csMid.Replace("  "," "));
			if(*((LPCTSTR)csMid + 1)==';'){
				delete psst;
				j = i + 1;
				continue;
			}
			if(csMid.GetLength() < 3){
				delete psst;
				j = i + 1;
				continue;
			}
			if(!ParseSylInfo(csMid,psst)){
				Empty();
				delete psst;
				return FALSE;
			}
			m_pdwSyl.Add((DWORD)psst);
			j = i + 1;
		}
	}
	return TRUE; 
}

/******************************************************************************************************************/
void CTextHandle::Empty()
{
	int i = 0;
	int nSize = m_pdwSyl.GetSize();
	while( i < nSize)
	{
		if(((SYLLABLESTRUCT *)(m_pdwSyl.GetAt(i)))->nNumberFo)
			delete[] ((SYLLABLESTRUCT *)(m_pdwSyl.GetAt(i)))->nFo;
		delete (SYLLABLESTRUCT *)(m_pdwSyl.GetAt(i));
		i++;		
	}
	m_pdwSyl.RemoveAll();
}

/******************************************************************************************************************/
void CTextHandle::RemoveAt(int i)
{
	m_pdwSyl.RemoveAt(i);
}
/******************************************************************************************************************/
//Neu stSyl.Flag co chua SYL_FOARRAY thi nguoi dung phai dam bao rang
//con tro stSyl.nFo tro den Buffer co do dai >= stSyl.nNumberFo * 4 (so byte danh cho kieu int)
//vi vay hay goi ham nay hai lan : Lan dau de lay ra stSyl.nNumberFo
//va lan thu hai moi lay ra stSyl.nFo
///////////////////////////////////////////////////
//			Bo xung ngay 16/10/2004				 //
//		Noi dung: them phan lay thong tin dp 3,4 //
///////////////////////////////////////////////////
BOOL CTextHandle::GetSylInfo(WORD wIndex,SYLLABLESTRUCT &stSyl)
{
	if(wIndex > m_pdwSyl.GetSize()-1) return FALSE;
	SYLLABLESTRUCT *psst = (SYLLABLESTRUCT *)m_pdwSyl.GetAt(wIndex);
	if(stSyl.wFlag & SYL_FIRSTUNIT)
	{
		strcpy(stSyl.cFirstAUnit,psst->cFirstAUnit);
		stSyl.bUnitIndex[0] = psst->bUnitIndex[0]; // Bo xung ngay 08 thang 12 nam 2005: lay chi so cua don vi am
	}
	if(stSyl.wFlag & SYL_SECONDUNIT&&(psst->nAUnit >= 2))
	{
		strcpy(stSyl.cSecondAUnit,psst->cSecondAUnit);
		stSyl.bUnitIndex[1] = psst->bUnitIndex[1]; // Bo xung ngay 08 thang 12 nam 2005: lay chi so cua don vi am
	}
	
	if(stSyl.wFlag &SYL_SYLLABLELEN)
		stSyl.nSyllableLen = psst->nSyllableLen;
	if(stSyl.wFlag & SYL_NUMOFUNIT)
		stSyl.nAUnit = psst->nAUnit;
	
	if(stSyl.wFlag & SYL_NUMBERFO)
		stSyl.nNumberFo = psst->nNumberFo;
	
	if(stSyl.wFlag & SYL_FOARRAY)
		memcpy(stSyl.nFo,psst->nFo,psst->nNumberFo * 4);
	//////////////////////////////////////////////////////////////////
	//	Sua doi ngay 31 thang 08 nam 2005							//
	//	Noi dung; them cac co SYL_TON, va cac lenh de lay gia tri	//
	//			  thanh dieu can tong hop							//
	//////////////////////////////////////////////////////////////////

	if((stSyl.wFlag & SYL_ENERGY)&&(stSyl.nNumberFo>0)&&(stSyl.wFlag & SYL_TON))
	{
		switch (stSyl.nNumberFo)
		{
			case 1: if((stSyl.nFo[0]>0) &&(stSyl.nFo[0]<=8)) 
					{
						stSyl.nNumberFo --;
						stSyl.nTon = stSyl.nFo[0];
						
						stSyl.nEnergy = 0;
					}
					else 
					{
						if((stSyl.nFo[0]>8) &&(stSyl.nFo[0]<=PSL_ENERGY_LEVELS)) // kiem tra nguong, de cho phep la F0
						{
							stSyl.nNumberFo --;
							stSyl.nEnergy = stSyl.nFo[0];
							stSyl.nTon	= 1; // mac dinh thanh dieu la thanh NGANG - LEVEL
						}
						/*else 
						{
							//stSyl.nEnergy =0;
							//stSyl.nTon	= 1;
						}*/ // Sua doi ngay 28 thang 11 nam 2005
					}
					break;
			case 2: if((stSyl.nFo[0] <=PSL_ENERGY_LEVELS)&&(stSyl.nFo[0]>0))// kiem tra nguong, de cho phep la F0
					{
						stSyl.nNumberFo --;
						stSyl.nEnergy = stSyl.nFo[0];
						for(int i=0; i<stSyl.nNumberFo; i++)
						stSyl.nFo[i] = stSyl.nFo[i+1];

						if((stSyl.nFo[1]>0)&&(stSyl.nFo[1]<=8))
						{
							stSyl.nNumberFo --;
							stSyl.nTon = stSyl.nFo[0];
							for(int i=0; i<stSyl.nNumberFo; i++)
								stSyl.nFo[i] = stSyl.nFo[i+1];
						}

					}
					else
					{
						stSyl.nEnergy = 0;
						stSyl.nTon = 0;
						/*stSyl.nNumberFo --;
						for(int i=0; i<stSyl.nNumberFo; i++)
						stSyl.nFo[i] = stSyl.nFo[i+1];*/// Sua doi ngay 28 thang 11 nam 2005
					}

					break;
			default: 
					if((stSyl.nFo[0] <=PSL_ENERGY_LEVELS)&&(stSyl.nFo[0]>0))// kiem tra nguong, de cho phep la F0
					{
						stSyl.nNumberFo --;
						stSyl.nEnergy = stSyl.nFo[0];
						for(int i=0; i<stSyl.nNumberFo; i++)
						stSyl.nFo[i] = stSyl.nFo[i+1];
					}
					else
					{
						stSyl.nEnergy = 0;
						stSyl.nTon = 0;
						
					}
					
					if(CPsola::BSettingInputText == TRUE)// Adding 24/12/2006 for modeling F0contour automatically
					{
						stSyl.nTon = psst->nTon;
						stSyl.nEnergy = psst->nEnergy;
						//stSyl.nEnergy = 20;
					}
				
					break;
		}
	}
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////////
//			Sua ngay 28 thang 10 nam 2004												 //
//			Noi dung: tao cho ham co tac dung phan tich cau truc syllable, biet co bao	 //
//					  nhieu thanh phan cau tao thanh syllable + cac thong tin khac		 //
///////////////////////////////////////////////////////////////////////////////////////////

BOOL CTextHandle::ParseSylInfo(CString &csOrg,SYLLABLESTRUCT *stSyl)
{
	//Tim ten cua diphone thu nhat
	int i = 0;
	int j = 1;
	int index = 0;
	CString cs = csOrg;
	CString csTemp; //csStrOut;
	///MessageBox(::AfxGetMainWnd()->m_hWnd,"1"+cs+"1",0,0);

	stSyl->nAUnit = 0;
	i = cs.Find(' ',j);	
	index = cs.Find(':',j);
	if( i - j > 4 ){
	
		if((i - j > 7) || (index == -1)|| (index -j >4))
		{
			this->m_nErrorCode = TH_UNITNOTFOUND;
			this->m_csError = "Fatal error in line : " + cs + "\n\n" + "AUnit : \"" + cs.Mid(j,i-j) + "\" not found";
			return FALSE;
		}
	}
	stSyl->bUnitIndex[0] = 1;
	if((index > j)&&(index < i))
	{
		csTemp = cs.Mid(index + 1, i - index -1);
		stSyl->bUnitIndex[0] = atoi(LPCSTR(csTemp));
	} // Ket thuc bo xung

	if ((index == -1)||(index > i)) index = i;// Sua doi ngay 08 thang 12 nam 2005


	memcpy(stSyl->cFirstAUnit,(LPCTSTR)cs + j,index-j); // Sua doi ngay 08 thang 12 nam 2005
	stSyl->cFirstAUnit[index-j] = '\0';// Sua doi ngay 08 thang 12 nam 2005
	stSyl->nAUnit++;
	
	int nTemp = 0;

	//Truong hop la SILENCE
	if((i-j == 1) && (stSyl->cFirstAUnit[0] == '_'))
	{
		//Tinh tong tat ca so theo sau vao silence 
		cs.Delete(0,i+1);
		stSyl->nNumberFo = 0;
		stSyl->nFo = NULL;
		stSyl->cSecondAUnit[0]='\0';
		stSyl->nSyllableLen = 0;
		i=0;
		j=0;
		while((i = cs.Find(' ',j))!=-1)
		{
			nTemp = atoi((LPCTSTR)cs + j);
			if(!IsNumeric((LPCTSTR)cs + j,i-j)||(nTemp < 0)){
				this->m_nErrorCode = TH_SILENCELENNOTNUMERIC;
				this->m_csError = "Fatal error in line : " + csOrg + "\n\nSilence Len : \"" + cs.Mid(j,i-j) + "\" not matched";
				return FALSE;
			}
			stSyl->nSyllableLen += nTemp;
			j = i + 1;
		}
		stSyl->nSyllableLen *= BYTESPERSAMPLE;
		return TRUE;
	}

	//Neu khong phai SILENCE
	//Tim ten diphone thu hai
	//************************************ Sua doi ngay 09/02 *****************************************************//
	//**	Noi dung: Dam bao la mot don vi am cho vao cung co the bien doi duoc cac thanh dieu, do do co the	***//
	//**			  ket noi cac syllabe voi nhau cung nhu bien doi thanh dieu cua mot van tuy y				***//
	//*************************************************************************************************************//
	j = i + 1;
	i = cs.Find(' ',j);
	index = cs.Find(':',j); // bo xung 08 thang 12 nam 2006

	if(i == -1)// Kiem tra xem con thong tin phia truoc khong, neu co thi co the hoac la Don vi am ke tiep hoac la So
				// neu khong thi du lieu se khong co thong tin ve chieu dai syllabe va tan so
	
	{
		stSyl->nSyllableLen = 0;
		stSyl->nFo = NULL;
		stSyl->nNumberFo = 0;
		return TRUE;
	}
	else 
	{
		nTemp = atoi((LPCTSTR)cs + j);
		if(!IsNumeric((LPCTSTR)cs + j,i-j) || (nTemp < 0) )
		{
			if( i - j > 4 ) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
			{
				if((i - j > 7) || (index == -1)|| (index -j >4))
				{
					this->m_nErrorCode = TH_UNITNOTFOUND;
					this->m_csError = "Fatal error in line : " + cs + "\n\nAUnit : \"" + cs.Mid(j,i-j) + "\" not found";
					return FALSE;
				}
			}
			stSyl->bUnitIndex[1] = 1;
			if((index > j)&&(index < i)) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
			{
				csTemp = cs.Mid(index + 1, i - index -1);
				stSyl->bUnitIndex[1] = atoi(LPCSTR(csTemp));
			} // Ket thuc bo xung
			if ((index == -1)||(index > i)) index = i;// Sua doi ngay 08 thang 12 nam 2005
			memcpy(stSyl->cSecondAUnit,(LPCTSTR)cs + j,index-j);
			stSyl->cSecondAUnit[index-j] = '\0';
			stSyl->nAUnit++;

		}
		else
		{
			stSyl->nSyllableLen = nTemp * BYTESPERSAMPLE;

			//Tim chuoi Fo
			cs.Delete(0,i + 1);
			stSyl->nNumberFo = cs.Replace(' ','\t');
			if(stSyl->nNumberFo == 0){
				stSyl->nFo = NULL;
				return TRUE;
			}
			stSyl->nFo = new int [stSyl->nNumberFo];
			i=0;
			j=0;
			int nCount = 0;
			while((i = cs.Find('\t',j))!=-1)
			{
				nTemp = atoi((LPCTSTR)cs + j);
				if(!IsNumeric((LPCTSTR)cs + j,i-j)||(nTemp <= 0)){
					delete[] stSyl->nFo;
					this->m_nErrorCode = TH_FONOTNUMERIC;
					this->m_csError = "Fatal error in line : " + csOrg + "\n\nFo Value : \"" + cs.Mid(j,i-j) + "\" not matched";
					return FALSE;
				}
				stSyl->nFo[nCount] = nTemp;
				nCount++;
				j = i + 1;
			}
			return TRUE;
		}

	}


	///////////////////////////////////////////////////////
	//				Bo xung cac diphone khac			///
	///////////////////////////////////////////////////////

	j = i + 1;
	i = cs.Find(' ',j);
	index = cs.Find(':',j); // bo xung 08 thang 12 nam 2006
	
	if(i == -1) // Kiem tra xem con thong tin phia truoc khong, neu co thi co the hoac la Don vi am ke tiep hoac la So
				// neu khong thi du lieu se khong co thong tin ve chieu dai syllabe va tan so
	{
		/*this->m_nErrorCode = TH_UNITNOTPAIR;
		this->m_csError = "Fatal error in line : " + cs + "\n\n" + "At AUnit Pair : \"" + csOrg + "\"";
		return FALSE;*/
		stSyl->nSyllableLen = 0;
		stSyl->nFo = NULL;
		stSyl->nNumberFo = 0;
		return TRUE;
	}
	else 
	{
		nTemp = atoi((LPCTSTR)cs + j);
		if(!IsNumeric((LPCTSTR)cs + j,i-j) || (nTemp < 0) )
		{
			if( i - j > 4 )
			{
				if((i - j > 7) || (index == -1)|| (index -j >4)) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
				{
					this->m_nErrorCode = TH_UNITNOTFOUND;
					this->m_csError = "Fatal error in line : " + cs + "\n\nAUnit : \"" + cs.Mid(j,i-j) + "\" not found";
					return FALSE;
				}
			}
			stSyl->bUnitIndex[2] = 1;
			if((index > j)&&(index < i)) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
			{
				csTemp = cs.Mid(index + 1, i - index -1);
				stSyl->bUnitIndex[2] = atoi(LPCSTR(csTemp));
			} // Ket thuc bo xung
			if ((index == -1)||(index > i)) index = i;// Sua doi ngay 08 thang 12 nam 2005
			memcpy(stSyl->cThirdAUnit,(LPCTSTR)cs + j,index-j);
			stSyl->cThirdAUnit[index-j] = '\0';
			stSyl->nAUnit++;

		}
		else
		{
			stSyl->nSyllableLen = nTemp * BYTESPERSAMPLE;

		//Tim chuoi Fo
			cs.Delete(0,i + 1);
			stSyl->nNumberFo = cs.Replace(' ','\t');
			if(stSyl->nNumberFo == 0){
				stSyl->nFo = NULL;
				return TRUE;
			}
			stSyl->nFo = new int [stSyl->nNumberFo];
			i=0;
			j=0;
			int nCount = 0;
			while((i = cs.Find('\t',j))!=-1)
			{
				nTemp = atoi((LPCTSTR)cs + j);
				if(!IsNumeric((LPCTSTR)cs + j,i-j)||(nTemp <= 0)){
					delete[] stSyl->nFo;
					this->m_nErrorCode = TH_FONOTNUMERIC;
					this->m_csError = "Fatal error in line : " + csOrg + "\n\nFo Value : \"" + cs.Mid(j,i-j) + "\" not matched";
					return FALSE;
				}
				stSyl->nFo[nCount] = nTemp;
				nCount++;
				j = i + 1;
			}
			return TRUE;
		}

	}
	
	// Nhap vao don vi am thu 4 neu co. maximum co 4 don vi am
	j = i + 1;
	i = cs.Find(' ',j);
	index = cs.Find(':',j); // bo xung 08 thang 12 nam 2006
	if(i == -1)// Kiem tra xem con thong tin phia truoc khong, neu co thi co the hoac la Don vi am ke tiep hoac la So
				// neu khong thi du lieu se khong co thong tin ve chieu dai syllabe va tan so
	{
		stSyl->nSyllableLen = 0;
		stSyl->nFo = NULL;
		stSyl->nNumberFo = 0;
		return TRUE;
	}
	else 
	{
		nTemp = atoi((LPCTSTR)cs + j);
		if(!IsNumeric((LPCTSTR)cs + j,i-j) || (nTemp < 0) )
		{
			if( i - j > 4 )
			{
				if((i - j > 7) || (index == -1)|| (index -j >4)) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
				{
					this->m_nErrorCode = TH_UNITNOTFOUND;
					this->m_csError = "Fatal error in line : " + cs + "\n\nAUnit : \"" + cs.Mid(j,i-j) + "\" not found";
					return FALSE;
				}
			}
			stSyl->bUnitIndex[3] = 1;
			if((index > j)&&(index < i)) // Bo xung ngay 08 thang 12 nam 2005, cho phu hop voi cau truc moi
			{
				csTemp = cs.Mid(index + 1, i - index -1);
				stSyl->bUnitIndex[3] = atoi(LPCSTR(csTemp));
			} // Ket thuc bo xung
			if ((index == -1)||(index > i)) index = i;// Sua doi ngay 08 thang 12 nam 2005
			memcpy(stSyl->cFourthAUnit,(LPCTSTR)cs + j,index-j);
			stSyl->cFourthAUnit[index-j] = '\0';
			stSyl->nAUnit++;
			//this->m_nErrorCode = TH_LENNOTNUMERIC;
			//this->m_csError = "Fatal error in line : " + csOrg + "\n\nSyllable Len : \"" + cs.Mid(j,i-j) + "\" not matched";
			//return FALSE;
		}
		else
		{
			stSyl->nSyllableLen = nTemp * BYTESPERSAMPLE;

		//Tim chuoi Fo
			cs.Delete(0,i + 1);
			stSyl->nNumberFo = cs.Replace(' ','\t');
			if(stSyl->nNumberFo == 0){
				stSyl->nFo = NULL;
				return TRUE;
			}
			stSyl->nFo = new int [stSyl->nNumberFo];
			i=0;
			j=0;
			int nCount = 0;
			while((i = cs.Find('\t',j))!=-1)
			{
				nTemp = atoi((LPCTSTR)cs + j);
				if(!IsNumeric((LPCTSTR)cs + j,i-j)||(nTemp <= 0)){
					delete[] stSyl->nFo;
					this->m_nErrorCode = TH_FONOTNUMERIC;
					this->m_csError = "Fatal error in line : " + csOrg + "\n\nFo Value : \"" + cs.Mid(j,i-j) + "\" not matched";
					return FALSE;
				}
				stSyl->nFo[nCount] = nTemp;
				nCount++;
				j = i + 1;
			}
			return TRUE;
		}

	}
	///////////////////////////////////////////////////////

	//Tim do dai Syllable
	j = i + 1;
	i = cs.Find(' ',j);
	if(i == -1){
		stSyl->nSyllableLen = 0;
		stSyl->nFo = NULL;
		stSyl->nNumberFo = 0;
		return TRUE;
	}

	nTemp = atoi((LPCTSTR)cs + j);
	if(!IsNumeric((LPCTSTR)cs + j,i-j) || (nTemp < 0) )
	{
		this->m_nErrorCode = TH_LENNOTNUMERIC;
		this->m_csError = "Fatal error in line : " + csOrg + "\n\nSyllable Len : \"" + cs.Mid(j,i-j) + "\" not matched";
		return FALSE;
	}
	
	stSyl->nSyllableLen = nTemp * BYTESPERSAMPLE;

	//Tim chuoi Fo
	cs.Delete(0,i + 1);
	stSyl->nNumberFo = cs.Replace(' ','\t');
	if(stSyl->nNumberFo == 0){
		stSyl->nFo = NULL;
		return TRUE;
	}
	stSyl->nFo = new int [stSyl->nNumberFo];
	i=0;
	j=0;
	int nCount = 0;
	while((i = cs.Find('\t',j))!=-1)
	{
		nTemp = atoi((LPCTSTR)cs + j);
		if(!IsNumeric((LPCTSTR)cs + j,i-j)||(nTemp <= 0)){
			delete[] stSyl->nFo;
			this->m_nErrorCode = TH_FONOTNUMERIC;
			this->m_csError = "Fatal error in line : " + csOrg + "\n\nFo Value : \"" + cs.Mid(j,i-j) + "\" not matched";
			return FALSE;
		}
		stSyl->nFo[nCount] = nTemp;
		nCount++;
		j = i + 1;
	}
	return TRUE;
}

int CTextHandle::GetSylCount()
{
	return m_pdwSyl.GetSize();
}

void CTextHandle::UpdateSylInfo(int index, SYLLABLESTRUCT Syllable)
{
	//strcpy(((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->cFirstAUnit,Syllable.cFirstAUnit);
	((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->bUnitIndex[0] = Syllable.bUnitIndex[0];

	if(Syllable.nAUnit>=2)
	{
	//	strcpy(((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->cSecondAUnit,Syllable.cSecondAUnit);
		((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->bUnitIndex[1] = Syllable.bUnitIndex[1];
	}
	if(Syllable.nAUnit>=3)
	{
	//	strcpy(((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->cThirdAUnit,Syllable.cThirdAUnit);
		((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->bUnitIndex[2] = Syllable.bUnitIndex[2];
	}
	if(Syllable.nAUnit==4)
	{
	//	strcpy(((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->cFourthAUnit,Syllable.cFourthAUnit);
		((SYLLABLESTRUCT*)(m_pdwSyl.ElementAt(index)))->bUnitIndex[3] = Syllable.bUnitIndex[3];
	}


}

BOOL CTextHandle::SyllableAnalysis(UNITINFOFULL &DicSyllable)
{


	BYTE bTone;
	int nNumOfVowel = VowelArray.GetSize();

	float	PosInPhrase,PosInWord, PosInSyntagm;
	BOOL	Stress;
	
	CString csSyllable;
	csSyllable	= DicSyllable.cUnitName;
	PosInPhrase = DicSyllable.PosInPhrase;
	PosInSyntagm= DicSyllable.PosInSyntagm;
	PosInWord	= DicSyllable.PosInWord;
	Stress		= DicSyllable.Stress;
	//////////////////////////////////////////////////
	//Begin analyzing the componants of the syllable
	//			01. Tone
	//			02.	phoneme
	//			03. phoneme type
	/////////////////////////////////////////////////
	for(BYTE k=0; k<4;k++)
	{
		DicSyllable.csSound[k] = "NUL";
		DicSyllable.csSoundType[k] = "NUL";
	}
	DicSyllable.bNumOfSound = 0;
	if((csSyllable =="SIL")|| (csSyllable =="SILP")||(csSyllable =="SILS")) 
	{
		bTone = 0;
		//DicSyllable.cUnitName = csSyllable;
	}
	else
	{
		for(int j=0; j< nNumOfVowel; j++)
		{
			int nFound = csSyllable.Find(VowelArray.GetAt(j),0);
			if(nFound== -1) bTone = 1;
			else 
			{
				bTone = ToneArray.GetAt(j);
				if (bTone == 5)
				{
					BYTE SylLen=0,posTemp=0;
					SylLen = csSyllable.GetLength();
					posTemp = csSyllable.Find("ch",1);
					if((csSyllable.GetAt(SylLen-1) =='c')||(csSyllable.GetAt(SylLen-1) =='t')
							||(csSyllable.GetAt(SylLen-1) =='p')||(posTemp == (SylLen-2)))
						bTone = 7;
				}
				if (bTone == 6)
				{
					BYTE SylLen=0,posTemp=0;
					SylLen = csSyllable.GetLength();
					posTemp = csSyllable.Find("ch",1);

					if((csSyllable.GetAt(SylLen-1) =='c')||(csSyllable.GetAt(SylLen-1) =='t')
						||(csSyllable.GetAt(SylLen-1) =='p')||(posTemp == (SylLen-2)))
						bTone = 8;
				}
				break;
			}
		}
		/////////////////////////////////////////////////////////
		// Get the information of the struture of syllables
		/////////////////////////////////////////////////////////
		for(j=0; j< DicSyllableArray.GetSize(); j++)
		{
			if(csSyllable == DicSyllableArray.GetAt(j).cUnitName)
			{
				DicSyllable = DicSyllableArray.GetAt(j);
				break;
			}
		}
		if(j==DicSyllableArray.GetSize()) 
		{
			///////////////////////////////////////
			/*		bao loi ra ngoai file debug	 */
			///////////////////////////////////////
			CString strOut;
			strOut = "The syllable: \"" + csSyllable +"\" does not exist in the dictionary";
			CPsola::OutputLastError(strOut);
			////////////////////////////////////////
			//DicSyllable.cUnitName = csSyllable;
			return FALSE;
		}
		/////////////////////////////////////////////////////////
		// End of Adding 30/08/2006 
		// Get the information of the struture of syllables
		/////////////////////////////////////////////////////////
		SyllableStructureAnalyse(DicSyllable);
	}
	DicSyllable.PosInPhrase	= PosInPhrase;
	DicSyllable.PosInSyntagm= PosInSyntagm;
	DicSyllable.PosInWord	= PosInWord;
	DicSyllable.Stress		= Stress;
	DicSyllable.bTone = bTone;

	return TRUE;

}

BOOL CTextHandle::LoadDictionary()
{
	FILE *fp;
	////////////////////////////////////////////////
	// Take a list of syllable in the dictionary and their prononciation
	CString csFilename;
	csFilename = CsDirectoryOfFile + "\\PronunciationDictionary.dic";

	//if( (fp = fopen("C:\\Documents and Settings\\Tran Do Dat\\My Documents\\Doctorat au Vietnam\\TDPSOLA MICA\\PronunciationDictionary.dic", "rt")) == NULL ) 
	if( (fp = fopen(csFilename, "rt")) == NULL ) 
	{
		///////////////////////////////////////
		/*		bao loi ra ngoai file debug	 */
		///////////////////////////////////////
		CString strOut;
		strOut = "Can not open file: PronunciationDictionary.dic";
		FILE* fp = fopen(CPsola::CsNameOfDebugFile,"a");
		fputs(strOut, fp);
		fclose(fp);
		////////////////////////////////////////
		
		return FALSE;
	}

	UNITINFOFULL DicSyllable;
		
	CString csText, csInfo, csTemp;
	int nNumOfSylInDic =0;
	
	fseek(fp,0,SEEK_SET);
	fseek(fp,0,SEEK_END);
	
	long lSizeOfFile = ftell(fp);
	fseek(fp,0,SEEK_SET);
	
	char *Buff;
	Buff = new char[lSizeOfFile+1];
		
	fread(Buff,lSizeOfFile,1,fp);
	Buff[lSizeOfFile] = NULL;

	csText.Format("%s",Buff+3);
	csText.TrimLeft();
	csText.TrimRight();
	lSizeOfFile = csText.GetLength();

	delete[] Buff;

	long lBegPos=0, lEndPos=0, lLastTabPos;
	int nStart=0,nEnd=0;
		
	fclose(fp);

	lLastTabPos = csText.ReverseFind('\t');
		
	for(;;)
	{
		//if(lEndPos >=lLastTabPos) break;
		lEndPos = csText.Find('\n',lBegPos+1);
		if((lEndPos == -1)||(lEndPos >=lLastTabPos)) 
			csInfo = csText.Mid(lBegPos, lSizeOfFile - lBegPos);
		else	
			csInfo = csText.Mid(lBegPos, lEndPos - lBegPos);
		
		nEnd = csInfo.Find('\t',0);
		csTemp = csInfo.Mid(0,nEnd);
		csTemp.TrimLeft();
		csTemp.TrimRight();
		DicSyllable.cUnitName = csTemp;
		nStart = nEnd;

		BYTE bNumOfSound;
		bNumOfSound=0;
		for(;;)
		{
			nEnd = csInfo.Find(' ',nStart+1);
			if(nEnd ==-1) 
			{
				csTemp = csInfo.Mid(nStart,csInfo.GetLength() - nStart);
				csTemp.TrimLeft();
				csTemp.TrimRight();
				DicSyllable.csSound[bNumOfSound] = csTemp;
				bNumOfSound++;
				break;
			}
			csTemp = csInfo.Mid(nStart,nEnd - nStart);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			DicSyllable.csSound[bNumOfSound] = csTemp;
			bNumOfSound++;
			nStart = nEnd;
		}
			
		DicSyllable.bNumOfSound = bNumOfSound;
		
		DicSyllableArray.Add(DicSyllable);
		nNumOfSylInDic++;
		if((lEndPos == -1)||(lEndPos >=lLastTabPos)) break;
		lBegPos = lEndPos;
	}

	//////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////

	return TRUE;

}

void CTextHandle::SyllableStructureAnalyse(UNITINFOFULL &SylOUT)
{
	UNITINFOFULL SylIN;
	SylIN = SylOUT;
	int i,j;
	for(i =0;i<SylIN.bNumOfSound; i++)
	{
		for(j=0;j<PhoneArray.GetSize();j++)
			if(SylIN.csSound[i] == PhoneArray.GetAt(j).csPhoneId)
				SylIN.csSoundType[i] = PhoneArray.GetAt(j).csPhoneType;
	}
	
	

	
	switch (SylIN.bNumOfSound)
	{
	case 4:
		SylOUT = SylIN;
		break;
	case 1:
		SylOUT.csSound[0] = "NUL";
		SylOUT.csSound[1] = "NUL";
		SylOUT.csSound[2] = SylIN.csSound[0];
		SylOUT.csSound[3] = "NUL";
		
		SylOUT.csSoundType[0] = "NUL";
		SylOUT.csSoundType[1] = "NUL";
		SylOUT.csSoundType[2] = SylIN.csSoundType[0];
		SylOUT.csSoundType[3] = "NUL";
		break;
	case 2:
		for(j =0; j< PhoneArray.GetSize()- NUMOFFINALSOUNDS;j++)
			if(SylIN.csSound[0] == PhoneArray.GetAt(j).csPhoneId)
			{
				if(j < NUMOFINITIALCONSONANTS)
				{
					SylOUT.csSound[0] = SylIN.csSound[0];
					SylOUT.csSound[1] = "NUL";
					SylOUT.csSound[2] = SylIN.csSound[1];
					SylOUT.csSound[3] = "NUL";

					SylOUT.csSoundType[0] = SylIN.csSoundType[0];
					SylOUT.csSoundType[1] = "NUL";
					SylOUT.csSoundType[2] = SylIN.csSoundType[1];
					SylOUT.csSoundType[3] = "NUL";
				}
				if(j== NUMOFINITIALCONSONANTS )
				{
					SylOUT.csSound[0] = "NUL";
					SylOUT.csSound[1] = SylIN.csSound[0];
					SylOUT.csSound[2] = SylIN.csSound[1];
					SylOUT.csSound[3] = "NUL";

					SylOUT.csSoundType[0] = "NUL";
					SylOUT.csSoundType[1] = SylIN.csSoundType[0];
					SylOUT.csSoundType[2] = SylIN.csSoundType[1];
					SylOUT.csSoundType[3] = "NUL";
				}
				if(j> NUMOFINITIALCONSONANTS )
					{
					SylOUT.csSound[0] = "NUL";
					SylOUT.csSound[1] = "NUL";
					SylOUT.csSound[2] = SylIN.csSound[0];
					SylOUT.csSound[3] = SylIN.csSound[1];

					SylOUT.csSoundType[0] = "NUL";
					SylOUT.csSoundType[1] = "NUL";
					SylOUT.csSoundType[2] = SylIN.csSoundType[0];
					SylOUT.csSoundType[3] = SylIN.csSoundType[1];
				}
				break;
			}
		break;
	case 3:
		for(j =0; j<= NUMOFINITIALCONSONANTS;j++)
		{
			//CString csID;
			//int ntet = PhoneArray.GetSize();
			//csID = PhoneArray.GetAt(j).csPhoneId;
			if(SylIN.csSound[0] == PhoneArray.GetAt(j).csPhoneId)
			{
				if(j < NUMOFINITIALCONSONANTS)
				{
					SylOUT.csSound[0] = SylIN.csSound[0];
					
					SylOUT.csSoundType[0] = SylIN.csSoundType[0];
					
					if(SylIN.csSound[1]=="w")
					{
						SylOUT.csSound[1] = SylIN.csSound[1];
						SylOUT.csSound[2] = SylIN.csSound[2];
						SylOUT.csSound[3] = "NUL";

						SylOUT.csSoundType[1] = SylIN.csSoundType[1];
						SylOUT.csSoundType[2] = SylIN.csSoundType[2];
						SylOUT.csSoundType[3] = "NUL";
					}
					else
					{
						SylOUT.csSound[1] = "NUL";
						SylOUT.csSound[2] = SylIN.csSound[1];
						SylOUT.csSound[3] = SylIN.csSound[2];

						SylOUT.csSoundType[1] = "NUL";
						SylOUT.csSoundType[2] = SylIN.csSoundType[1];
						SylOUT.csSoundType[3] = SylIN.csSoundType[2];
					}

				}
				if(j== NUMOFINITIALCONSONANTS )
				{
					SylOUT.csSound[0] = "NUL";
					SylOUT.csSound[1] = SylIN.csSound[0];
					SylOUT.csSound[2] = SylIN.csSound[1];
					SylOUT.csSound[3] = SylIN.csSound[2];

					SylOUT.csSoundType[0] = "NUL";
					SylOUT.csSoundType[1] = SylIN.csSoundType[0];
					SylOUT.csSoundType[2] = SylIN.csSoundType[1];
					SylOUT.csSoundType[3] = SylIN.csSoundType[2];
				}
				
				break;
			}
		}
		break;
		
	}

}

BOOL CTextHandle::LoadPhoneme()
{
	FILE *fp;
	UNITINFOFULL DicSyllable;
	
	CString csText, csInfo, csTemp, csListOfPhone;

	PHONESTRUCTINFO PhoneElement;
	
	int nNumOfSylInDic =0;
	CString csFileName;
	csFileName = CsDirectoryOfFile + "\\PhonemeVietnamienne.dic";
	
	if( (fp = fopen(csFileName, "rt")) == NULL ) 
		{
			csFileName = "Can not open file: PhonemeVietnamienne.dic";
			CPsola::OutputLastError(csFileName);
			
			return FALSE;
		}

	fseek(fp,0,SEEK_SET);
	fseek(fp,0,SEEK_END);
	long lSizeOfFile = ftell(fp);
	fseek(fp,0,SEEK_SET);
	
	char *Buff;
	Buff = new char[lSizeOfFile+1];
			
	fread(Buff,lSizeOfFile,1,fp);
	Buff[lSizeOfFile] = NULL;

	csText.Format("%s",Buff);
	csText.TrimLeft();
	csText.TrimRight();
	lSizeOfFile = csText.GetLength();

	delete[] Buff;

	long lBegPos=0, lEndPos=0;
	int nStart=0,nEnd=0;
		
	fclose(fp);
	
	///////////////////////////////////////////////////////////////
	// Get all of the initial consonants
	///////////////////////////////////////////////////////////////
	lBegPos = csText.Find("{PAD}",0);
	lEndPos = csText.Find("{EOPAD}",0);

	csListOfPhone = csText.Mid(lBegPos, lEndPos - lBegPos);
	
	lEndPos = csListOfPhone.Find('\n',0);
	lBegPos = lEndPos;
	
	for(;;)
		{
			lEndPos = csListOfPhone.Find('\n',lBegPos+1);
			if(lEndPos == -1) break;
				
			csInfo = csListOfPhone.Mid(lBegPos, lEndPos - lBegPos);
			nEnd = csInfo.Find('\t',0);
			csTemp = csInfo.Mid(0,nEnd);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneId = csTemp;
			
			nStart = nEnd;
			nEnd = csInfo.Find('\t',nStart + 1);
			csTemp = csInfo.Mid(nStart+1,nEnd - nStart);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneType = csTemp;

			nStart = nEnd;
			csTemp = csInfo.Mid(nStart+1,csInfo.GetLength()-nStart-1);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csCharId = csTemp;

			InPhoneArray.Add(PhoneElement);
			//PhoneArray.Add(PhoneElement);
			//if(lEndPos == -1) break;
			lBegPos = lEndPos;
		//	nNumOfPhone[0] ++;
		}
	////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////
	// Get all of the semivowel
	///////////////////////////////////////////////////////////////
	PhoneElement.csPhoneId = "w";
	PhoneElement.csPhoneType = "SV";
	PhoneElement.csCharId	= "o";
	MiPhoneArray.Add(PhoneElement);

	PhoneElement.csPhoneId = "w";
	PhoneElement.csPhoneType = "SV";
	PhoneElement.csCharId	= "u";
	MiPhoneArray.Add(PhoneElement);
	
	//PhoneArray.Add(PhoneElement);
	//nNumOfPhone[1] = 1;
	
	///////////////////////////////////////////////////////////////
	// Get all of the vowels
	///////////////////////////////////////////////////////////////
	
	lBegPos = csText.Find("{NA}",0);
	lEndPos = csText.Find("{EONA}",0);

	csListOfPhone = csText.Mid(lBegPos, lEndPos - lBegPos);
	
	lEndPos = csListOfPhone.Find('\n',0);
	lBegPos = lEndPos;
	
	for(;;)
		{
			lEndPos = csListOfPhone.Find('\n',lBegPos+1);
			if(lEndPos == -1) 	break;
			
			csInfo = csListOfPhone.Mid(lBegPos, lEndPos - lBegPos);
			nEnd = csInfo.Find('\t',0);
			csTemp = csInfo.Mid(0,nEnd);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneId = csTemp;
			
			nStart = nEnd;
			nEnd = csInfo.Find('\t',nStart + 1);
			csTemp = csInfo.Mid(nStart+1,nEnd - nStart);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneType = csTemp;

			nStart = nEnd;
			csTemp = csInfo.Mid(nStart+1,csInfo.GetLength()-nStart-1);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csCharId = csTemp;
			
			VoArray.Add(PhoneElement);
			//PhoneArray.Add(PhoneElement);
			//if(lEndPos == -1) break;

			lBegPos = lEndPos;
		//	nNumOfPhone[2] ++;
		}
	////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////
	// Get all of the final sounds
	///////////////////////////////////////////////////////////////
	
	lBegPos = csText.Find("{AC}",0);
	lEndPos = csText.Find("{EOAC}",0);

	csListOfPhone = csText.Mid(lBegPos, lEndPos - lBegPos);
	
	lEndPos = csListOfPhone.Find('\n',0);
	lBegPos = lEndPos;
	
	for(;;)
		{
			lEndPos = csListOfPhone.Find('\n',lBegPos+1);
			if(lEndPos == -1) break;
			
			csInfo = csListOfPhone.Mid(lBegPos, lEndPos - lBegPos);
			nEnd = csInfo.Find('\t',0);
			csTemp = csInfo.Mid(0,nEnd);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneId = csTemp;
			
			nStart = nEnd;
			nEnd = csInfo.Find('\t',nStart + 1);
			csTemp = csInfo.Mid(nStart+1,nEnd - nStart);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csPhoneType = csTemp;

			nStart = nEnd;
			csTemp = csInfo.Mid(nStart+1,csInfo.GetLength()-nStart-1);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			PhoneElement.csCharId = csTemp;

			FiPhoneArray.Add(PhoneElement);
			//if(lEndPos == -1) break;
			lBegPos = lEndPos;
		//	nNumOfPhone[3] ++;
		}
	////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////
/*	// For testing 
	FILE *fOut;
	char text[256];
		if( (fOut = fopen("Phoneme.dic", "wt")) == NULL ) 
		{
			MessageBox("Can not open this file");
			return FALSE;
		}

		int TestdwSize = PhoneArray.GetSize();

		for(int it=0; it<TestdwSize;it++)
		{
			PhoneElement = PhoneArray.GetAt(it);
			sprintf(text,"%s \t %s \n",PhoneElement.csPhoneId, PhoneElement.csPhoneType);
			fwrite(text,strlen(text),1,fOut);
		}
		fclose(fOut);*/
	///////////////////////////////////////////////////////////
		
	return TRUE;

}

void CTextHandle::LoadVowelAndTone()
{
	FILE *fVow;
	////////////////////////////////////////////////////////////////////////////////////////////
	// Take the vowels with their tones
	////////////////////////////////////////////////////////////////////////////////////////////
	
	CString csFilename;
	CString csText, csInfo, csTemp;
	BYTE bTone;
	csFilename = CsDirectoryOfFile + "\\vowel_tone_ABC.dic";
	
	if((fVow = fopen(csFilename, "rt")) == NULL ) 
		{
			csFilename = "Can not open file: vowel_tone.dic";
			CPsola::OutputLastError(csFilename);
			return;
		}

	fseek(fVow,0,SEEK_SET);
	fseek(fVow,0,SEEK_END);
	long lSizeOfFile = ftell(fVow);
	fseek(fVow,0,SEEK_SET);
	
	char *Buff;
	Buff = new char[lSizeOfFile+1];
			
	fread(Buff,lSizeOfFile,1,fVow);
	Buff[lSizeOfFile] = NULL;

	csText.Format("%s",Buff);
	csText.TrimLeft();
	csText.TrimRight();
	lSizeOfFile = csText.GetLength();

	delete[] Buff;

	long lBegPos=0, lEndPos=0;
	int nStart=0,nEnd=0;
		
	fclose(fVow);
	
	///////////////////////////////////////////////////////////////
	// Get all of the initial consonants
	///////////////////////////////////////////////////////////////
	lBegPos = csText.Find("{NA}",0);
	lEndPos = csText.Find("{EONA}",0);

	csText = csText.Mid(lBegPos, lEndPos - lBegPos);
	
	lEndPos = csText.Find('\n',0);
	lBegPos = lEndPos;
	
	for(;;)
		{
			lEndPos = csText.Find('\n',lBegPos+1);
			if(lEndPos == -1) break;
				
			csInfo = csText.Mid(lBegPos, lEndPos - lBegPos);
			nEnd = csInfo.Find('\t',0);
			csTemp = csInfo.Mid(0,nEnd);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			VowelArray.Add(csTemp);
			
			nStart = nEnd;
			nEnd = csInfo.Find('\t',nStart + 1);
			csTemp = csInfo.Mid(nStart+1,nEnd-nStart);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			VowelNoToneArray.Add(csTemp);
			
			nStart = nEnd;
			csTemp = csInfo.Mid(nStart+1,csInfo.GetLength()-nStart-1);
			csTemp.TrimLeft();
			csTemp.TrimRight();
			bTone = atoi(csTemp);
			ToneArray.Add(bTone );
						
			lBegPos = lEndPos;
		}

/*	BYTE bTone;
	char text[255];
	while( !feof( fVow ) )
	{
		fscanf( fVow,"%s", text );
		if( feof( fVow ) ) break;
		VowelArray.Add(text);

		fscanf( fVow,"%s", text );
		if( feof( fVow ) ) break;
		VowelNoToneArray.Add(text);

		fscanf( fVow,"%d", &bTone );
		if( feof( fVow ) ) break;
			
		ToneArray.Add( bTone );
		if( feof(fVow) ) break;
	}
	fclose(fVow);*/
	return;
	//int nNumOfVowel = Vowel.GetSize();

}

BOOL CTextHandle::DurationModel(UNITINFOFULL Unit, float &Length, int &node)
{
	/*Rules for node 2*/
	float mean = 0;

	if( Unit.Stress == FALSE )
	{
		node = 2;
		mean = 2966.68f;
  
		/*Rules for node 3*/
		if(( Unit.csSoundType[3] == "CSU") || (Unit.csSoundType[3] == "NUL") || (Unit.csSoundType[3] == "SV" ))
		{
			node = 3;
			mean = 2786.49f;
			/*Rules for node 4*/
			if((Unit.PosInWord == 0) ||(Unit.PosInWord == 2.0f/3) || (Unit.PosInWord == 0.75f ))
			{
				node = 4;
				mean = 2695.16f;
				/*Rules for node 5*/
				if(( Unit.csSoundType[0] == "CSU") || (Unit.csSoundType[0] == "NUL" ))
				{
					node = 5;
					mean = 2481.76f;
					/*Rules for terminal node 1*/
					if((Unit.csRightPhoneType == "CFL") || (Unit.csRightPhoneType == "CSN") || 
						(Unit.csRightPhoneType == "CSV") || (Unit.csRightPhoneType == "VF" ))
					{
						node = -1;
						mean = 2263.42f;
					}
					/*Rules for terminal node 2*/

					if((Unit.csRightPhoneType == "CFU") ||(Unit.csRightPhoneType == "CFV") ||(Unit.csRightPhoneType == "CSU") ||
						   (Unit.csRightPhoneType == "SV") ||(Unit.csRightPhoneType == "VB") ||(Unit.csRightPhoneType == "VBC") ||
						   (Unit.csRightPhoneType == "VFC") ||(Unit.csRightPhoneType == "VM") ||(Unit.csRightPhoneType == "VMC"))
					{
						node = -2;
						mean = 2606.69f;
					}
				}
				/*Rules for node 6*/

				if((Unit.csSoundType[0] == "CFL") || (Unit.csSoundType[0] == "CFU") || (Unit.csSoundType[0] == "CFV") ||
					   (Unit.csSoundType[0] == "CSN") || (Unit.csSoundType[0] == "CSV"))
				{
					node = 6;
					mean = 2812.22f;
					/*Rules for node 7*/
					if((Unit.csRightPhoneType == "CFL") || (Unit.csRightPhoneType == "CFU") || (Unit.csRightPhoneType == "CFV") ||
						   (Unit.csRightPhoneType == "CSN") || (Unit.csRightPhoneType == "CSV") || ( Unit.csRightPhoneType == "VBC") ||
						   (Unit.csRightPhoneType == "VFC") || (Unit.csRightPhoneType == "VMC"))
					
					{
						node = 7;
						mean = 2701.01f;
						/*Rules for terminal node 3*/
						if(Unit.PosInPhrase <= 0.465f )
						{
							node = -3;
							mean = 2583.1f;
						}
						/*Rules for terminal node 3*/

						if(  Unit.PosInPhrase > 0.465f )
						{
							node = -4;
							mean = 2805.1f;
						}
					}
					/*Rules for terminal node 5*/
					if((Unit.csRightPhoneType == "CSU") || (Unit.csRightPhoneType == "SV") || 
						(Unit.csRightPhoneType == "VB") || (Unit.csRightPhoneType == "VF") || (Unit.csRightPhoneType == "VM"))
					{
						node = -5;
						mean = 3037.18f;
					}
				}
			}
			/*Rules for terminal node 6*/

			if((Unit.PosInWord == 0.5f) ||(Unit.PosInWord == 1 ))
			{
				node = -6;
				mean = 3289.2f;
			}
		}
		/*Rules for node 8*/

		if( Unit.csSoundType[3] == "CSN" )
		{
			node = 8;
			mean = 3306.31f;
			
			/*Rules for node 9*/

			if( (Unit.csRightPhoneType == "CFL") || (Unit.csRightPhoneType == "CFU") || (Unit.csRightPhoneType == "CSN") ||
				(Unit.csRightPhoneType == "CSV") || (Unit.csRightPhoneType == "SV")  || (Unit.csRightPhoneType == "VB")  ||
				(Unit.csRightPhoneType == "VBC") || (Unit.csRightPhoneType == "VF")  || (Unit.csRightPhoneType == "VMC")) 
			{
				node = 9;
				mean = 3103;
				/*Rules for node 10*/

				if( Unit.PosInPhrase <= 0.98f )
				{
					node = 10;
					mean = 3087.51f;
					/*Rules for terminal node 7*/
					if( (Unit.csRightPhoneType == "CFL") || (Unit.csRightPhoneType == "CSN") ||
						(Unit.csRightPhoneType == "SV")  || (Unit.csRightPhoneType == "VBC"))
					{
						node = -7;
						mean = 2950.54f;
					}
					/*Rules for node 11*/
					if( (Unit.csRightPhoneType == "CFU") || (Unit.csRightPhoneType == "CSV") ||
						(Unit.csRightPhoneType == "VB")  || (Unit.csRightPhoneType == "VF") ||(Unit.csRightPhoneType == "VMC")) 
					{
						node = 11;
						mean = 3191.23f;
						/*Rules for terminal node 8*/
						if( (Unit.PosInWord == 0) || ( Unit.PosInWord == 0.5) ||
						    (Unit.PosInWord == 2.0f/3) || (Unit.PosInWord == 0.75))
						{
							node = -8;
							mean = 3105.44f;
						}
						/*Rules for terminal node 9*/
						if(Unit.PosInWord == 1 )
						{
							node = -9;
							mean = 3552.22f;
						}
					}
				}
				/*Rules for terminal node 10*/

				if( Unit.PosInPhrase > 0.98f )
				{
					node = -10;
					mean = 4466.15f;
				}
			}
		/*Rules for node 12*/
			if( (Unit.csRightPhoneType == "CFV") || (Unit.csRightPhoneType == "CSU") ||
				   (Unit.csRightPhoneType == "VFC") || (Unit.csRightPhoneType == "VM"))
			{
				node = 12;
				mean = 3532.28f;
				/*Rules for node 13*/
				if( (Unit.PosInWord == 0) || (Unit.PosInWord == 0.5f) ||
					  ( Unit.PosInWord == 2.0f/3) || (Unit.PosInWord == 0.75f) )
				{
					node = 13;
					mean = 3450.81f;
					/*Rules for terminal node 11*/
					if( ( Unit.bTone == 1) ||(Unit.bTone == 3) ||
						   (Unit.bTone == 7) || (Unit.bTone == 8))
					{
						node = -11;
						mean = 3280.94f;
					}
					/*Rules for terminal node 12*/
					if( ( Unit.bTone == 2) ||
						   (Unit.bTone == 4) ||
						   (Unit.bTone == 5) ||
						   (Unit.bTone == 6 ))
					{
						node = -12;
						mean = 3612.98f;
					}
				}
			/*Rules for terminal node 13*/
				if(Unit.PosInWord == 1 )
				{
					node = -13;
					mean = 3832.83f;
				}
			}

		}

	}

	/*Rules for node 14*/

	if( Unit.Stress == TRUE )

	{
		node = 14;
		mean = 4547.03f;
		/*Rules for terminal node 14*/

		if (( Unit.bTone == 6)  || ( Unit.bTone == 7) || ( Unit.bTone == 8))
		{
			node = -14;
			mean = 4025.34f;
		}
		/*Rules for node 15*/
		if (( Unit.bTone == 1) || (  Unit.bTone == 2) || ( Unit.bTone == 3) || (Unit.bTone == 4) ||(Unit.bTone == 5 ))
		{
			node = 15;
			mean = 4751.15f;
			/*Rules for node 16*/
			if((Unit.bRightTone == 1) || (Unit.bRightTone == 2) || (Unit.bRightTone == 3) ||
			   (Unit.bRightTone == 4) || (Unit.bRightTone == 5) || (Unit.bRightTone == 6) || (Unit.bRightTone == 7 ))
			{
				node = 16;
				mean = 4139.47f;
				/*Rules for terminal node 15*/
				if( Unit.PosInPhrase <= 0.345f )
				{
					node = -15;
					mean = 3805.06f;
				}
				/*Rules for terminal node 16*/

				if( Unit.PosInPhrase > 0.345f )
				{
					node = -16;
					mean = 4303.63f;
				}
			}
			/*Rules for node 17*/
			if(( Unit.bRightTone == 0) || (Unit.bRightTone == 8 ))
			{
				node = 17;
				mean = 5027.88f;
				/*Rules for node 18*/
				if((Unit.bTone == 1) || (Unit.bTone == 2) || (Unit.bTone == 4))
				{
					node = 18;
					mean = 4927.28f;
					/*Rules for terminal node 17*/
					if( (Unit.csRightPhoneType == "CFL") || (  Unit.csRightPhoneType == "CSN") ||
						(Unit.csRightPhoneType == "CSV") || (  Unit.csRightPhoneType == "SV") ||
						(Unit.csRightPhoneType == "VB")  || (Unit.csRightPhoneType == "VBC") ||
						(Unit.csRightPhoneType == "VFC") || (Unit.csRightPhoneType == "VM") ||
						(Unit.csRightPhoneType == "VMC"))
					{
						node = -17;
						mean = 4718.52f;
					}
				/*Rules for terminal node 18*/

					if( (Unit.csRightPhoneType == "CFU") || (  Unit.csRightPhoneType == "CFV") ||
						   (Unit.csRightPhoneType == "CSU") ||(Unit.csRightPhoneType == "VF" )||(Unit.csRightPhoneType == "NUL" ))
					{
						node = -18;
						mean = 5076.02f;
					}
				}
				/*Rules for terminal node 19*/
				if((Unit.bTone == 3) ||  (Unit.bTone == 5 ))
				{
					node = -19;
					mean = 5313.19f;
				}
			}
		}
	}
	Length = mean;
	return TRUE;

}


void CTextHandle::F0ContourGeneration(CArray<UNITINFOFULL, UNITINFOFULL> &SyllableArray)
{
	const double fRelRegMatrix[8][8] = {0.99, 0.84, 0.91, 0.82, 0.90, 0.88, 1.24, 0.84,
										1.13, 0.92, 0.96, 0.91, 0.99, 0.93, 1.38, 0.92,
										1.21, 1.05, 1.04, 1.07, 1.06, 1.11, 1.48, 1.09,
										1.13, 0.92, 0.94, 0.90, 0.98, 0.92, 1.39, 0.93,
										1.19, 1.08, 1.12, 1.05, 1.07, 1.18, 1.50, 1.18,
										1.11, 0.92, 0.90, 0.90, 0.95, 0.92, 1.36, 0.93,
										0.84, 0.73, 0.77, 0.68, 0.78, 0.80, 1.10, 0.70,
										1.14, 0.91, 0.96, 0.94, 0.98, 0.95, 1.45, 0.94};
	//CUIntArray F0_Contour;
	CArray<float, float> F0_Contour, F0_Syllable, F0_Register_Contour;
	float fOldNorRegister =1.0f;
	
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// Modeling F0 contour
	//////////////////////////////////////////////////////////////////////////////////////////////////
	int nNumOfSylInPhrase;
	int nSizeOfArray;
	int nNumOfF0InPhrase;
	nSizeOfArray = SyllableArray.GetSize();
	nNumOfSylInPhrase	= 0;
	nNumOfF0InPhrase	= 0;
	for( int i=0; i < nSizeOfArray; i++)
	{
		int nSample;
		float fNumOfF0; 
		int nNumOfF0;
		if(SyllableArray.GetAt(i).bTone>0)
		{
//			int nPosOfSyl;
			float fNorRegister;// = 1.0f;
			BYTE bLeftTone;
									
			fNorRegister = 1.0f;
			//nPosOfSyl = LookUpSylArray.GetSize()-1;
					
			bLeftTone = SyllableArray.GetAt(i-1).bTone;
			if(bLeftTone ==0) 
			{
						
				fNorRegister = 1.0f;
				F0_Syllable.RemoveAll();
				
				fNumOfF0 = float(SyllableArray.GetAt(i).dwUnitLen)/160;
				if((fNumOfF0 + 0.5f) > (int(fNumOfF0)+1)) SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0)+1;
				else SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0);

				for(nSample=0; nSample < SyllableArray.GetAt(i).numOfF0; nSample++) 
				{
					F0_Syllable.Add(fNorRegister);
					F0_Register_Contour.Add(fNorRegister);// For contour of the register of F0 of the phrase
				}
				ToneInPhrase(F0_Syllable, SyllableArray.GetAt(i).bTone, fNorRegister,SyllableArray.GetAt(i).dwUnitLen);
				for(nSample=0; nSample < SyllableArray.GetAt(i).numOfF0; nSample++) 
				{
					F0_Contour.Add(F0_Syllable.GetAt(nSample));
				}
				fOldNorRegister = fNorRegister;
				nNumOfF0InPhrase = nNumOfF0InPhrase + SyllableArray.GetAt(i).numOfF0;
				nNumOfSylInPhrase ++;
				if(SyllableArray.GetAt(i).bRightTone ==0)
				{
					int nF0BeginOfSyl =0;
					int nF0ContourSize = F0_Contour.GetSize();
					
					for(int nPosInPhrase = i-nNumOfSylInPhrase+1;nPosInPhrase <= i; nPosInPhrase++)
					{
						nNumOfF0 = SyllableArray.GetAt(nPosInPhrase).numOfF0;
						SyllableArray.ElementAt(nPosInPhrase).fF0 = new float[nNumOfF0];
						for(nSample=0;nSample < nNumOfF0; nSample++)
							SyllableArray.ElementAt(nPosInPhrase).fF0[nSample] = F0_Contour.GetAt(nF0ContourSize - nNumOfF0InPhrase + nF0BeginOfSyl + nSample);
						nF0BeginOfSyl = nF0BeginOfSyl + nNumOfF0;

					}

					nNumOfF0InPhrase = 0;
					nNumOfSylInPhrase= 0;
				}
			}
			else
			{
				fNorRegister = fOldNorRegister*float(fRelRegMatrix[bLeftTone-1][SyllableArray.GetAt(i).bTone-1]);
				F0_Syllable.RemoveAll();
				fNumOfF0 = float(SyllableArray.GetAt(i).dwUnitLen)/160;
				if((fNumOfF0 + 0.5f) > (int(fNumOfF0)+1)) SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0)+1;
				else SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0);
				
				for(nSample=0; nSample < SyllableArray.GetAt(i).numOfF0; nSample++) 
				{
					F0_Syllable.Add(fNorRegister);
					F0_Register_Contour.Add(fNorRegister);// For contour of the register of F0 of the phrase
				}
				
				fOldNorRegister = fNorRegister;
			
				ToneInPhrase(F0_Syllable, SyllableArray.GetAt(i).bTone, fNorRegister,SyllableArray.GetAt(i).dwUnitLen);

			
				/////////////////////////////////////////////////////////////////////////////////////
				// Smoothing two levels of register of Tone
				/////////////////////////////////////////////////////////////////////////////////////
				float fAverage, fTempReg;
				
				fAverage =  F0_Syllable.GetAt(0) - F0_Contour.GetAt(F0_Contour.GetSize() - 1); // Pr0 - Pl0 // Coarticulation at the endpoint of the first syllable
				
				
				if(bLeftTone == 6)
					for(nSample = 0; nSample < SyllableArray.GetAt(i).numOfF0/6; nSample ++)// Progressve Effect > Regressive Effect
					{
						//fTempReg = F0_Syllable.GetAt(nSample) - fAverage*(float)(DicSyllable.numOfF0/6 - nSample)/(DicSyllable.numOfF0/6);// Progressve Effect = Regressive Effect
						fTempReg = F0_Syllable.GetAt(nSample) - fAverage*(float)(SyllableArray.GetAt(i).numOfF0/6 - nSample)/(SyllableArray.GetAt(i).numOfF0/6);// Progressve Effect > Regressive Effect
						F0_Syllable.SetAt(nSample, fTempReg);
					}
				else
				{
					for(nSample = 0; nSample < SyllableArray.GetAt(i).numOfF0/3; nSample ++)// Progressve Effect > Regressive Effect
					{
						//fTempReg = F0_Syllable.GetAt(nSample) - fAverage*(float)(DicSyllable.numOfF0/6 - nSample)/(DicSyllable.numOfF0/6);// Progressve Effect = Regressive Effect
						fTempReg = F0_Syllable.GetAt(nSample) - fAverage*(float)(SyllableArray.GetAt(i).numOfF0/3 - nSample)/(SyllableArray.GetAt(i).numOfF0/3);// Progressve Effect > Regressive Effect
						F0_Syllable.SetAt(nSample, fTempReg);
					}
				}
				for(nSample=0; nSample < SyllableArray.GetAt(i).numOfF0; nSample++)
				F0_Contour.Add(F0_Syllable.GetAt(nSample));
				// End of Smoothing
				/////////////////////////////////////////////////////////////////////////////////////
				nNumOfF0InPhrase = nNumOfF0InPhrase + SyllableArray.GetAt(i).numOfF0;
				nNumOfSylInPhrase ++;
				if(SyllableArray.GetAt(i).bRightTone ==0)
				{
					int nF0BeginOfSyl =0;
					int nF0ContourSize = F0_Contour.GetSize();
					
					for(int nPosInPhrase = i-nNumOfSylInPhrase+1;nPosInPhrase <= i; nPosInPhrase++)
					{
						nNumOfF0 = SyllableArray.GetAt(nPosInPhrase).numOfF0;
						SyllableArray.ElementAt(nPosInPhrase).fF0 = new float[nNumOfF0];
						for(nSample=0;nSample < nNumOfF0; nSample++)
							SyllableArray.ElementAt(nPosInPhrase).fF0[nSample] = F0_Contour.GetAt(nF0ContourSize - nNumOfF0InPhrase + nF0BeginOfSyl + nSample);
						nF0BeginOfSyl = nF0BeginOfSyl + nNumOfF0;

					}

					nNumOfF0InPhrase = 0;
					nNumOfSylInPhrase= 0;
				}
				
			}
		}
		else 
		{
			fNumOfF0 = float(SyllableArray.GetAt(i).dwUnitLen)/160;
			if((fNumOfF0 + 0.5f) > (int(fNumOfF0)+1)) SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0)+1;
			else SyllableArray.ElementAt(i).numOfF0 = int(fNumOfF0);

			for(nSample=0; nSample < SyllableArray.GetAt(i).numOfF0; nSample++) 
			{
				F0_Contour.Add(0.0f);
				F0_Register_Contour.Add(0.0f);// For contour of the register of F0 of the phrase
			}
		}
	}

	//////////////////////////////////////////////////////////////////////////////////////////////
	// For test
	//////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////
/*	CString csFileName;
	csFileName = "F0Contour.FRE"; // F0RE = F0 REgister

	FILE *fOut;
	if( (fOut = fopen((LPCTSTR)csFileName, "wt")) == NULL ) 
	{
		csFileName = "Can not open file: F0Contour.FRE";
		CPsola::OutputLastError(csFileName);
		return;
	}

	char text[255];
	sprintf(text,"Time\tFrequency\n");
	fwrite(text,strlen(text),1,fOut);
		
	int dwSize = F0_Register_Contour.GetSize();

	for(i=0; i<dwSize;i++)
	{
		sprintf(text,"%7.2f\t%6.0f\n",float(i)*0.01f, CPsola::nF0_Begin*F0_Register_Contour.GetAt(i));
		fwrite(text,strlen(text),1,fOut);
	}
	F0_Register_Contour.RemoveAll();
	
	fclose(fOut);*/
			
			//////////////////////////////////////////////////////////////////////
/*	csFileName = "F0Contour.NOF"; // NOF = Normalized F0
	if( (fOut = fopen((LPCTSTR)csFileName, "wt")) == NULL ) 
	{
		csFileName = "Can not open file: F0Contour.NOF";
		CPsola::OutputLastError(csFileName);
		return;
	}

	sprintf(text,"Time\tFrequency\n");
	fwrite(text,strlen(text),1,fOut);
		
	dwSize = F0_Contour.GetSize();

	for(i=0; i<dwSize;i++)
	{
		sprintf(text,"%7.2f\t%6.0f\n",float(i)*0.01f, CPsola::nF0_Begin*F0_Contour.GetAt(i));
		fwrite(text,strlen(text),1,fOut);
	}
	fclose(fOut);*/
	
	// End of Test
	//////////////////////////////////////////////////////////////////////////////////////////////

	F0_Contour.RemoveAll();
	F0_Syllable.RemoveAll();
	F0_Register_Contour.RemoveAll();


}


// muc dich la tinh F0Array tu dau vao la F0Array, ToneType, fNorFo, nSyllen thaodv 260111
// dieu khien duong cong F0 theo tung loai thanh
BOOL CTextHandle::ToneInPhrase(CArray<float, float> &F0Array, BYTE ToneType, float fNorF0, int nSylLen)
{
	if ((ToneType<1) ||(ToneType>8)) return FALSE;
	int nNumOfCtrlPoint = 0;
	int counter = 0;
	
	/*int nValueOfF0_1[4] =	{100,100,95, 85};
	int nValueOfF0_2[4] =	{100, 95, 80, 75};
	//int nValueOfF0_3[8] = 	{100, 95, 85, 50, 50, 95, 120, 125};
	int nValueOfF0_3[8] = 	{100, 95, 85, 70, 70, 95, 120, 125};// for syllables in continuous speech
	//int nValueOfF0_4[5] =	{100, 90, 75, 65, 90};
	int nValueOfF0_4[5] =	{100, 95, 85, 70, 65};
	int nValueOfF0_5[4] =	{100,100,110, 125};
	//int nValueOfF0_6[5] =	{100, 95, 85, 55, 50};
	int nValueOfF0_6[5] =	{100, 95, 90, 80, 55};

	int nValueOfF0_7[3] =	{100,110, 125};
	int nValueOfF0_8[3] =	{100, 88, 65};*/

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// These patterns are used for modeling f0 contours
	int nValueOfF0_1[4] =	{100,100, 96, 90};
	int nValueOfF0_2[4] =	{100, 95, 91, 80};
	int nValueOfF0_3_S[8] = {100, 100, 95, 93, 90, 80, 80, 100}; // S = Short: for a syllable which has a short duration
	int nValueOfF0_3_M[8] = {100, 95, 85, 80, 70, 90, 100, 110}; // M = Medium: for a syllable which has a short duration
	int nValueOfF0_3[8] = 	{100, 95, 85, 70, 70, 95, 120, 125};// for syllables in continuous speech
	
	int nValueOfF0_4[5]  =	{100, 99, 85, 65, 75};
	int nValueOfF0_4M[5] =  {100, 99, 85, 70, 65}; 
	int nValueOfF0_5_S[4] =	{100,100,102, 105};
	int nValueOfF0_5_M[4] =	{100, 99,105, 125};
	int nValueOfF0_5[4] =	{100,100,105, 125};

	int nValueOfF0_6[5] =	{100, 95, 90, 80, 60};

	int nValueOfF0_7[3] =	{100,110, 125};
	int nValueOfF0_8[3] =	{100, 88, 65};
	///////////////////////////////////////////////////////////////////////////////////////////////////
	

	int nCtrlPosition_1[3] = {33,34,33};
	int nCtrlPosition_2[4] = {25,25,25,25};
	int nCtrlPosition_3[7] = {16, 17,12,10,12,17,16};
	int nCtrlPosition_6[4] = {20,15,15,50};
	int nCtrlPosition_7[2] = {40,60};

	int lTransitionPoint;
	
	int nLenOfSyl;
	float fF0Step,fF0Temp;
	int nPos;
	int nLen, nTotalLenOfSyl;
	float fLen;
	float fF0BigStep =0;
	
	
	CArray<float, float> OldF0Array;// dung de luu tam thoi gia tri F0 truoc khi copy vao F0Array; thaodv 260111

	OldF0Array.Copy(F0Array);
	F0Array.RemoveAll();
	
	
	nTotalLenOfSyl = OldF0Array.GetSize();

	lTransitionPoint = int(0.3f*nTotalLenOfSyl);
	
	nLenOfSyl = nTotalLenOfSyl - lTransitionPoint;

	if (ToneType == 1)
	{
		nNumOfCtrlPoint = 4;
		nPos =0;
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_1[counter+1] - nValueOfF0_1[counter])/nCtrlPosition_1[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_1[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_1[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen < nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			
			fF0Step = float(nValueOfF0_1[counter+1] - nValueOfF0_1[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_1[counter+1] - nValueOfF0_1[counter])/100;

		}

	}
	if (ToneType == 2)
	{
		nNumOfCtrlPoint = 4;
		nPos =0;
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_2[counter+1] - nValueOfF0_2[counter])/nCtrlPosition_1[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_1[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_1[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_2[counter+1] - nValueOfF0_2[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_2[counter+1] - nValueOfF0_2[counter])/100;
		}
	}

	if (ToneType == 3)
	{
		
		nNumOfCtrlPoint = 8;
		nPos =0;
		if((nSylLen/16) <= 150) for(int k =0; k<8;k++) nValueOfF0_3[k] = nValueOfF0_3_S[k];
		if(((nSylLen/16) > 150)&&((nSylLen/16) <= 250)) for(int k =0; k<8;k++) nValueOfF0_3[k] = nValueOfF0_3_M[k];

		
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_3[counter+1] - nValueOfF0_3[counter])/nCtrlPosition_3[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_3[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_3[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			
			fF0Step = float(nValueOfF0_3[counter+1] - nValueOfF0_3[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_3[counter+1] - nValueOfF0_3[counter])/100;

		}

	}

	if (ToneType == 4)
	{
		
		nNumOfCtrlPoint = 5;
		nPos =0;
		if((nSylLen/16) <= 250) for(int k =0; k<5;k++) nValueOfF0_4[k] = nValueOfF0_4M[k];
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_4[counter+1] - nValueOfF0_4[counter])/nCtrlPosition_2[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_2[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_2[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_4[counter+1] - nValueOfF0_4[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_4[counter+1] - nValueOfF0_4[counter])/100;

		}

		
	}
	
	if (ToneType == 5)
	{
		nNumOfCtrlPoint = 4;
		nPos =0;
		if((nSylLen/16) <= 150) for(int k =0; k<4;k++) nValueOfF0_5[k] = nValueOfF0_5_S[k];
		if(((nSylLen/16) > 150)&&((nSylLen/16) <= 250)) for(int k =0; k<4;k++) nValueOfF0_5[k] = nValueOfF0_5_M[k];
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_5[counter+1] - nValueOfF0_5[counter])/nCtrlPosition_1[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_1[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_1[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_5[counter+1] - nValueOfF0_5[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_5[counter+1] - nValueOfF0_5[counter])/100;

		}

	}

	if (ToneType == 6)
	{
		nNumOfCtrlPoint = 5;
		nPos =0;
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_6[counter+1] - nValueOfF0_6[counter])/nCtrlPosition_6[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_6[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_6[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_6[counter+1] - nValueOfF0_6[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_6[counter+1] - nValueOfF0_6[counter])/100;

		}

	
	}

	if (ToneType == 7)
	{
		
		nNumOfCtrlPoint = 3;
		nPos =0;
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_7[counter+1] - nValueOfF0_7[counter])/nCtrlPosition_7[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_7[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_7[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_7[counter+1] - nValueOfF0_7[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_7[counter+1] - nValueOfF0_7[counter])/100;

		}

	
	}

	if (ToneType == 8)
	{
		nNumOfCtrlPoint = 3;
		nPos =0;
		
		for(counter = 0; counter < nNumOfCtrlPoint-1;counter++)
		{
			//fF0Step = float(nValueOfF0_8[counter+1] - nValueOfF0_8[counter])/nCtrlPosition_7[counter]/100;

			fLen = float(nLenOfSyl* nCtrlPosition_7[counter])/100;
			nLen = nLenOfSyl* nCtrlPosition_7[counter]/100;
			if((float(nLen) + 0.5f)< fLen) nLen++;
			if(lTransitionPoint + nPos + nLen >= nTotalLenOfSyl) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;
			if((counter == (nNumOfCtrlPoint-2))&& (lTransitionPoint + nPos + nLen <nTotalLenOfSyl)) nLen = nTotalLenOfSyl- lTransitionPoint - nPos;

			fF0Step = float(nValueOfF0_8[counter+1] - nValueOfF0_8[counter])/nLen/100;

			for(int i = 0; i <nLen; i++)
			{
				fF0Temp = OldF0Array.GetAt(lTransitionPoint + nPos + i) + fF0Step*i + fF0BigStep;
				OldF0Array.SetAt(lTransitionPoint + nPos + i, fF0Temp);
			}
			nPos = nPos + nLen;
			fF0BigStep = fF0BigStep + float(nValueOfF0_8[counter+1] - nValueOfF0_8[counter])/100;
		}	
	}

	float fOffset =1;
	float fAverage =0;
	if((ToneType!=3)&&(ToneType!=6))
	{
		for(int j = int(nTotalLenOfSyl*0.3f) ; j<int(nTotalLenOfSyl*0.8f);j++)
			fAverage = OldF0Array.GetAt(j)+ fAverage;
			
		fAverage = fAverage/ (int(nTotalLenOfSyl*0.8f) - int(nTotalLenOfSyl*0.3f));
		fOffset = fNorF0 - fAverage;
		
		for(int i=0; i<nTotalLenOfSyl; i ++)
			OldF0Array.ElementAt(i) = OldF0Array.ElementAt(i) + fOffset;
	}

	F0Array.Copy(OldF0Array);

	OldF0Array.RemoveAll();
	
	return TRUE;

}

BOOL CTextHandle::ParseSylInfo(UNITINFOFULL &Syllable, SYLLABLESTRUCT *stSyl)
{
	//Tim ten cua diphone thu nhat
	int i = 0;
	//int j = 1;
	//int index = 0;
	
	//MessageBox(::AfxGetMainWnd()->m_hWnd,"1"+cs+"1",0,0);

	if((Syllable.cUnitName =="SILP")||(Syllable.cUnitName =="SILS")||(Syllable.cUnitName =="SIL"))
	{
		stSyl->nAUnit = 0;
		stSyl->nNumberFo = 0;
		stSyl->nFo = NULL;
		stSyl->cFirstAUnit[0] = '_';
		stSyl->cFirstAUnit[1] = '\0';
		stSyl->cSecondAUnit[0]='\0';
		
		stSyl->nSyllableLen = Syllable.dwUnitLen*BYTESPERSAMPLE;
		
		return TRUE;
	}
	else
	{
		stSyl->nAUnit		= Syllable.bNumOfSubUnit;
		stSyl->nTon			= Syllable.bTone;
		stSyl->nSyllableLen	= Syllable.dwUnitLen *BYTESPERSAMPLE;
		stSyl->nEnergy		= Syllable.dwEnergy;
		stSyl->nNumberFo	= Syllable.numOfF0;
		stSyl->nFo			= new int[stSyl->nNumberFo];
		for(i=0; i<stSyl->nNumberFo; i++)
		{
			stSyl->nFo[i] = int(Syllable.fF0[i] * CPsola::nF0_Begin *fRegister);
			if(stSyl->nFo[i] < int(0.5f* CPsola::nF0_Begin)) stSyl->nFo[i] = int(0.55f* CPsola::nF0_Begin);
			//stSyl->bUnitIndex[i] = 1;
		}
		for(i=0; i<stSyl->nAUnit;i++) stSyl->bUnitIndex[i] = 1;

		switch (stSyl->nAUnit)
		{
		case 1: 
			strcpy(stSyl->cFirstAUnit,Syllable.csSubUnit[0]);
			break;
		case 2:
			strcpy(stSyl->cFirstAUnit,Syllable.csSubUnit[0]);
			strcpy(stSyl->cSecondAUnit,Syllable.csSubUnit[1]);
			break;
		case 3:
			strcpy(stSyl->cFirstAUnit,Syllable.csSubUnit[0]);
			strcpy(stSyl->cSecondAUnit,Syllable.csSubUnit[1]);
			strcpy(stSyl->cThirdAUnit,Syllable.csSubUnit[2]);
			break;
		case 4:
			strcpy(stSyl->cFirstAUnit,Syllable.csSubUnit[0]);
			strcpy(stSyl->cSecondAUnit,Syllable.csSubUnit[1]);
			strcpy(stSyl->cThirdAUnit,Syllable.csSubUnit[2]);
			strcpy(stSyl->cFourthAUnit,Syllable.csSubUnit[3]);
			break;
		}
	}
	return TRUE;

}

BYTE CTextHandle::EnergyModel(UNITINFOFULL Unit)
{
	CString csVowel[16]	= {"a", "A", "B", "E", "e", "i", "O", "o", "7", "Z", "Q", "u", "M", "I", "U", "Y"};
	BYTE SylEnergy[16]	= { 26,  28,  26,  31,  30,  23,  25,  22,  20,  20,  24, 15 ,  17,  32,  19, 18};  
	BYTE bSylEnergy = 32;

	for(int i= 0; i<16; i++)
		if(Unit.csSound[2] == csVowel[i]) 
		{
			bSylEnergy = SylEnergy[i]; break;
		}
	
	switch (Unit.bTone)
	{
		case 1: bSylEnergy = BYTE(bSylEnergy*0.95f);
				break;
		case 2: bSylEnergy = BYTE(bSylEnergy*0.85f);
				break;
		case 4: bSylEnergy = BYTE(bSylEnergy*0.75f);
				break;
		case 5: bSylEnergy = BYTE(bSylEnergy*0.9f);
				break;
		case 6: bSylEnergy = BYTE(bSylEnergy*0.95f);
				break;
	}

	if((Unit.PosInSyntagm ==1)&&(Unit.nPhraseLen>1)) bSylEnergy = BYTE(bSylEnergy*0.8f);

	return bSylEnergy;

}

BOOL CTextHandle::SyllableAnalysis(CString &csSyllable, UNITINFOFULL &DicSyllable)
{

	int nNumOfVow, nNumOfInPhone, nNumOfMiPhone, nNumOfFiPhone;
	
	// Getting tone information
	int nNumOfVowel = VowelArray.GetSize();
	int nFound;

	// Initial phone	
	DicSyllable.csSound[0]		= "NUL";
	DicSyllable.csSoundType[0]	= "NUL";
	// middle phone
	DicSyllable.csSound[1]		= "NUL";
	DicSyllable.csSoundType[1]	= "NUL";
	// nucleus phone
	DicSyllable.csSound[2]		= "NUL";
	DicSyllable.csSoundType[2]	= "NUL";
	// final phone
	DicSyllable.csSound[3]		= "NUL";
	DicSyllable.csSoundType[3]	= "NUL";

	if((csSyllable =="SIL")|| (csSyllable =="SILP")||(csSyllable =="SILS")) 
	{
		DicSyllable.bTone = 0;
		DicSyllable.bNumOfSound =0;
		return TRUE;
	}
		
	nFound = -1;
	for(int j=0; j< nNumOfVowel; j++)
	{
		nFound = csSyllable.Find(VowelArray.GetAt(j),0);
		
		if(nFound>=0)
		{
			DicSyllable.bTone = ToneArray.GetAt(j);
			if (DicSyllable.bTone == 5)
			{
				BYTE SylLen=0,posTemp=0;
				SylLen = csSyllable.GetLength();
				posTemp = csSyllable.Find("ch",1);
				if((csSyllable.GetAt(SylLen-1) =='c')||(csSyllable.GetAt(SylLen-1) =='t')
							||(csSyllable.GetAt(SylLen-1) =='p')||(posTemp == (SylLen-2)))
					DicSyllable.bTone = 7;
			}
			if (DicSyllable.bTone == 6)
			{
				BYTE SylLen=0,posTemp=0;
				SylLen = csSyllable.GetLength();
				posTemp = csSyllable.Find("ch",1);

				if((csSyllable.GetAt(SylLen-1) =='c')||(csSyllable.GetAt(SylLen-1) =='t')
						||(csSyllable.GetAt(SylLen-1) =='p')||(posTemp == (SylLen-2)))
						DicSyllable.bTone = 8;
			}
			if(DicSyllable.bTone >1) csSyllable.Replace(VowelArray.GetAt(j),VowelNoToneArray.GetAt(j));
			break;
		}
	}
	if(nFound == -1) DicSyllable.bTone =1;

	// Getting other information
	DicSyllable.bNumOfSound = 0;
	nNumOfVow		= VoArray.GetSize();
	nNumOfInPhone	= InPhoneArray.GetSize();
	nNumOfMiPhone	= MiPhoneArray.GetSize();
	nNumOfFiPhone	= FiPhoneArray.GetSize();

	CString csLeft, csRight;

	int	i;
//	BYTE bTone;
	BYTE bPhoneLen;
	BYTE bSyllableLen;
	nFound = -1;
	
	for(i=0 ; i< nNumOfVow; i++)
	{
		CString csVow;
		csVow = VoArray.GetAt(i).csCharId;
		//nFound = csSyllable.Find(VoArray.GetAt(i).csCharId,0);
		nFound = csSyllable.Find(csVow,0);

		//if(nFound== -1) bTone = 1;
		//else
		if(nFound !=-1)
		{
			bSyllableLen = csSyllable.GetLength();
			//Vowell No 1
			if(VoArray.GetAt(i).csPhoneId == "M7") // it does exist the Semivowel for middle phone in this case.
			{
				//nucleous phone
				DicSyllable.csSound[2]		= "M7";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				
				if(csLeft.GetLength()>0)
				{
					for(int k=0; k<InPhoneArray.GetSize(); k++)
						if(InPhoneArray.GetAt(k).csCharId == csLeft)
						{
							DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
							DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(k==InPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}
				
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
					
				}
					
				break;
			}
			//Vowell No 2
			if(VoArray.GetAt(i).csPhoneId == "uo")
			{
				//nucleous phone
				DicSyllable.csSound[2]		= "uo";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					if((csLeft == "q")&&(VoArray.GetAt(i).csCharId = "ua")) 
					{
						//nucleous phone
						DicSyllable.csSound[2]		= "a";
						DicSyllable.csSoundType[2]	= "VM";
				
						// middle phone
						DicSyllable.csSound[1]		= "w";
						DicSyllable.csSoundType[1]	= "SV";

						// initial phone
						DicSyllable.csSound[0]		= "k";
						DicSyllable.csSoundType[0]	= "CSU";

					}
					else
					{
						for(int k=0; k<InPhoneArray.GetSize(); k++)
							if(InPhoneArray.GetAt(k).csCharId == csLeft)
							{
								DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
								DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}

						if(i==InPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
				}
				
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
					
				}
				break;
			}
			//Vowell No 3
			if(VoArray.GetAt(i).csPhoneId == "ie")
			{
				//nucleous phone
				DicSyllable.csSound[2]		= "ie";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					if(csLeft == "g") 
					{
						if(VoArray.GetAt(i).csCharId == "ia")
						{
							DicSyllable.csSound[2]		= "NUL";
							DicSyllable.csSoundType[2]	= "NUL";
							continue;
						}
						else
						{
							// initial phone
							DicSyllable.csSound[0]		="z";
							DicSyllable.csSoundType[0]	= "CFV";
						}
					}
					else
					{
						int nMidFound = -1;
					
						nMidFound = csLeft.Find(MiPhoneArray.GetAt(0).csCharId,0);
						if(nMidFound == -1)	nMidFound = csLeft.Find(MiPhoneArray.GetAt(1).csCharId,0);

						if(nMidFound == -1)
						{
							for(int k=0; k<InPhoneArray.GetSize(); k++)
								if(InPhoneArray.GetAt(k).csCharId == csLeft)
								{
									DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
									DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
									DicSyllable.bNumOfSound++;
									break;
								}

							if(k==InPhoneArray.GetSize())
							{
								CString csStrOut;
								csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
								CPsola::OutputLastError(csStrOut);
								return FALSE;
							}
						}
						else
						{
							DicSyllable.csSound[1]		= "w";
							DicSyllable.csSoundType[1]	= "SV";
							DicSyllable.bNumOfSound++;
							csLeft = csLeft.Left(nMidFound);
							if(csLeft.GetLength()>0)
							{
								for(int k=0; k<InPhoneArray.GetSize(); k++)
									if(InPhoneArray.GetAt(k).csCharId == csLeft)
									{
										DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
										DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
										DicSyllable.bNumOfSound++;
										break;
									}
								if(k==InPhoneArray.GetSize())
								{
									CString csStrOut;
									csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
									CPsola::OutputLastError(csStrOut);
									return FALSE;
								}
							}
						}
					}
				}
			
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}
				break;
			}
			//Vowell No 4, Vowell No 5, Vowell No 6
			if((VoArray.GetAt(i).csPhoneId == "M")||(VoArray.GetAt(i).csPhoneId == "7")||(VoArray.GetAt(i).csPhoneId == "o"))
			{
				// nucleous phone
				DicSyllable.csSound[2]		= VoArray.GetAt(i).csPhoneId; //"M";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					for(int k=0; k<InPhoneArray.GetSize(); k++)
						if(InPhoneArray.GetAt(k).csCharId == csLeft)
						{
							DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
							DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(k==InPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}

				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
					
				}
				break;
			}
		
			//Vowell No 7, Vowell No 8, Vowell No 9, Vowell No 10
			if((VoArray.GetAt(i).csPhoneId == "e")||(VoArray.GetAt(i).csPhoneId == "E")||(VoArray.GetAt(i).csPhoneId == "7X")||(VoArray.GetAt(i).csPhoneId == "aX"))
			{
				DicSyllable.csSound[2]		= VoArray.GetAt(i).csPhoneId;//"E";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					int nMidFound = -1;
					
					nMidFound = csLeft.Find(MiPhoneArray.GetAt(0).csCharId,0);
					if(nMidFound == -1)	nMidFound = csLeft.Find(MiPhoneArray.GetAt(1).csCharId,0);

					if(nMidFound == -1)
					{
						for(int k=0; k<InPhoneArray.GetSize(); k++)
							if(InPhoneArray.GetAt(k).csCharId == csLeft)
							{
								DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
								DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}
						if(k==InPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
					else
					{
						DicSyllable.csSound[1]		= "w";
						DicSyllable.csSoundType[1]	= "SV";
						DicSyllable.bNumOfSound++;
						csLeft = csLeft.Left(nMidFound);
						if(csLeft.GetLength()>0)
						{
							for(int k=0; k<InPhoneArray.GetSize(); k++)
								if(InPhoneArray.GetAt(k).csCharId == csLeft)
								{
									DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
									DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
									DicSyllable.bNumOfSound++;
									break;
								}
							if(k==InPhoneArray.GetSize())
							{
								CString csStrOut;
								csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
								CPsola::OutputLastError(csStrOut);
								return FALSE;
							}
						}
					}
				}
				
				// Checking Right Size of the Syllable

				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}

				break;
			}

			//Vowell No 11
			if(VoArray.GetAt(i).csPhoneId == "a")
			{
				DicSyllable.csSound[2]		= "a";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;

				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				
				if(csLeft.GetLength()>0)
				{
					int nMidFound = -1;
					
					nMidFound = csLeft.Find(MiPhoneArray.GetAt(0).csCharId,0);
					
					if(nMidFound == -1)	nMidFound = csLeft.Find(MiPhoneArray.GetAt(1).csCharId,0);

					if(nMidFound == -1)
					{
						for(int k=0; k<InPhoneArray.GetSize(); k++)
							if(InPhoneArray.GetAt(k).csCharId == csLeft)
							{
								DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
								DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}
						if(k==InPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
					else
					{
						DicSyllable.csSound[1]		= "w";
						DicSyllable.csSoundType[1]	= "SV";
						DicSyllable.bNumOfSound++;
						csLeft = csLeft.Left(nMidFound);
						if(csLeft.GetLength()>0)
						{
							for(int k=0; k<InPhoneArray.GetSize(); k++)
								if(InPhoneArray.GetAt(k).csCharId == csLeft)
								{
									DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
									DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
									DicSyllable.bNumOfSound++;
									break;
								}
							if(k==InPhoneArray.GetSize())
							{
								CString csStrOut;
								csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
								CPsola::OutputLastError(csStrOut);
								return FALSE;
							}
						}
					}
				}
				// Checking Right Size of the Syllable

				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							if((FiPhoneArray.GetAt(j).csCharId == "nh")||(FiPhoneArray.GetAt(j).csCharId == "ch"))
							{
								DicSyllable.csSound[2]		= "EX";
								DicSyllable.csSoundType[2]	= "VFC";
							}
							if((FiPhoneArray.GetAt(j).csCharId =="u")||(FiPhoneArray.GetAt(j).csCharId == "y"))
							{
								DicSyllable.csSound[2]		= "aX";
								DicSyllable.csSoundType[2]	= "VMC";
							}
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}
				break;
			}
			//Vowell No 12
			if(VoArray.GetAt(i).csPhoneId == "O")
			{
				DicSyllable.csSound[2]		= "O";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;
				
				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					for(int k=0; k<InPhoneArray.GetSize(); k++)
						if(InPhoneArray.GetAt(k).csCharId == csLeft)
						{
							DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
							DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(k==InPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}
			
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							if(((DicSyllable.csSound[3] == "NG")||(DicSyllable.csSound[3] == "k"))&&(VoArray.GetAt(i).csCharId!="oo"))
							{
								DicSyllable.csSound[2]		= "OX";
								DicSyllable.csSoundType[2]	= "VBC";
							}
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
				}
				break;
			}

			//Vowell No 16
			if(VoArray.GetAt(i).csPhoneId == "u")
			{
				DicSyllable.csSound[2]		= "u";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;

				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					
					int nMidFound = -1;
					nMidFound = csLeft.Find("i",0);
					
					if(nMidFound == -1)
					{
						for(int k=0; k<InPhoneArray.GetSize(); k++)
							if(InPhoneArray.GetAt(k).csCharId == csLeft)
							{
								DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
								DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}
						if(k==InPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
					else
					{
						csLeft = csLeft.Left(nMidFound);
						if(csLeft.GetLength()>0)
						{
							if(csLeft == "g")
							{
								DicSyllable.csSound[0]		="z";
								DicSyllable.csSoundType[0]	= "CFV";
							}
							else
							{
								DicSyllable.csSound[2]		= "i";
								DicSyllable.csSoundType[2]	= "VF";
														
								for(int k=0; k<InPhoneArray.GetSize(); k++)
									if(InPhoneArray.GetAt(k).csCharId == csLeft)
									{
										DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
										DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
										DicSyllable.bNumOfSound++;
										break;
									}
								if(k==InPhoneArray.GetSize())
								{
									CString csStrOut;
									csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
									CPsola::OutputLastError(csStrOut);
									return FALSE;
								}

								DicSyllable.csSound[3]		= "w";
								DicSyllable.csSoundType[3]	= "SV";
								DicSyllable.bNumOfSound++;
								return TRUE;
							}
						}
						
					}
				}
				
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					if(csRight !="y")
					{
						for(int j=0; j< FiPhoneArray.GetSize();j++)
							if(FiPhoneArray.GetAt(j).csCharId == csRight)
							{
								DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
								DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}
						if(j==FiPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
					else
					{
						DicSyllable.csSound[1]		= "w";
						DicSyllable.csSoundType[1]	= "SV";
						DicSyllable.bNumOfSound++;

						DicSyllable.csSound[2]		= "i";
						DicSyllable.csSoundType[2]	= "VF";

					}
				}
				break;
			}
			//Vowell No 13
			if(VoArray.GetAt(i).csPhoneId == "i")
			{
				DicSyllable.csSound[2]		= "i";
				DicSyllable.csSoundType[2]	= VoArray.GetAt(i).csPhoneType;
				DicSyllable.bNumOfSound++;

				// For the initial and final phones
				csLeft= csSyllable.Left(nFound);
				bPhoneLen = VoArray.GetAt(i).csCharId.GetLength();
				csRight = csSyllable.Right(bSyllableLen - nFound -bPhoneLen);
				
				// Checking Left Size of the Syllable
				if(csLeft.GetLength()>0)
				{
					if(csLeft == "g") 
					{
						// initial phone
						DicSyllable.csSound[0]		="z";
						DicSyllable.csSoundType[0]	= "CFV";
					}
					else
					{
						for(int k=0; k<InPhoneArray.GetSize(); k++)
							if(InPhoneArray.GetAt(k).csCharId == csLeft)
							{
								DicSyllable.csSound[0]		= InPhoneArray.GetAt(k).csPhoneId;
								DicSyllable.csSoundType[0]	= InPhoneArray.GetAt(k).csPhoneType;
								DicSyllable.bNumOfSound++;
								break;
							}
						if(k==InPhoneArray.GetSize())
						{
							CString csStrOut;
							csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csLeft);
							CPsola::OutputLastError(csStrOut);
							return FALSE;
						}
					}
				}
				
				// Checking Right Size of the Syllable
				if(csRight.GetLength()>0)
				{
					for(int j=0; j< FiPhoneArray.GetSize();j++)
						if(FiPhoneArray.GetAt(j).csCharId == csRight)
						{
							DicSyllable.csSound[3]		= FiPhoneArray.GetAt(j).csPhoneId;
							DicSyllable.csSoundType[3]	= FiPhoneArray.GetAt(j).csPhoneType;
							DicSyllable.bNumOfSound++;
							break;
						}
					if(j==FiPhoneArray.GetSize())
					{
						CString csStrOut;
						csStrOut.Format("Acoustic unit : %s does not exist in Vietnamese!\n",csRight);
						CPsola::OutputLastError(csStrOut);
						return FALSE;
					}
					
				}
				break;
			}
			
		}
	}

	return TRUE;

}
void CTextHandle::WriteToTextFile(CString cstr)
{
	//ofstream txtFile2("txt_TextHandle.txt");
	txtFile2.open("txt_TextHandle.txt",ios::app);
	if (txtFile2.is_open())
	  {
		//txtFile2 << "This is a line.\n";
		//txtFile2 << "This is another line.\n";
		txtFile2 <<cstr <<" ";
		txtFile2.close();
	  }
	  else cout << "Unable to open file";
		
}
///////////
//dau vao la csLocation: duong dan toi csdl text
//doc file co so du lieu text va luu vao trong bo nho.
//
BOOL CTextHandle::LoadSylTextData(CString csLocation)
{
	BOOL bResult = false;
	FILE * pFile;
	
	const int nMaxNumOfChar = 512;
	int i = 0;
	char * cLine="";
	pFile = fopen (csLocation, "r");
//	fgets(cLine,nMaxNumOfChar,pFile);
	if(pFile != NULL)
	{
		while(fgets(cLine,nMaxNumOfChar,pFile))
		{   
			i++;
			if(i==1) continue;
			//cout << "this is a line: "<<cLine<<endl;
			SaveSylDB(cLine);
		
			bResult = true;
		}
	}		
	fclose(pFile);
	//Ket thuc doc file text
	cout << "finish read DB text file"<<endl;
	//cout << SylTextArray.ElementAt(0).csSyllableName<<endl;
	return bResult;
}
///////
//Doc tung dong trong file csdl text va luu vao SylTextArray
BOOL CTextHandle::SaveSylDB(CString cLine)
{
	CString result[50];
	int nSpaceStartIndex = 0;
	int nSpaceNextIndex = 0;
	int i = 0, nSpaceLastIndex=0, nSizeOfResult = 0;
	cLine = NormalizeString(cLine);
	//WriteToTextFile(cLine);

	while((nSpaceNextIndex = cLine.Find(' ',nSpaceStartIndex) )!=-1)
	{
		//cout<<"start: "<<nSpaceStartIndex<<endl;
	//	cout<<"next: "<<nSpaceNextIndex<<endl;
		result[i] = cLine.Mid(nSpaceStartIndex, nSpaceNextIndex-nSpaceStartIndex);
		nSpaceLastIndex = nSpaceNextIndex;
		nSpaceStartIndex = nSpaceNextIndex+1;
		//WriteToTextFile(result[i]);
		i++;

	}
	result[i] = cLine.Mid(nSpaceLastIndex,cLine.GetLength());
	//WriteToTextFile(result[i]);
	nSizeOfResult = i;
	///////////////////////////////////
	
	SylTextElement.csSyllableName= result[0];
	SylTextElement.bTone = atoi(result[1]); // chua ep kieu
	SylTextElement.bLength = atoi(result[2]);
	SylTextElement.bBeginIndex= 0; // chi so dau tien o trong file wav
	SylTextElement.bEndIndex= 0;//chua xong thaodv 100311
	SylTextElement.nPosition= atoi(result[3]); // vi tri cua am tiet trong cau, SIL va am tiet dau tien mang gia tri 0, am tiet sau mang gia tri 2
	SylTextElement.nPhraseLen= atoi(result[4]); // do dai cua cau
	SylTextElement.nNumOfPhone= atoi(result[6]);
	SylTextElement.csCarryingFile= result[11];
	SylTextElement.csInitial= result[12];
	SylTextElement.csMiddle= result[13];
	SylTextElement.csNucleus= result[14];
	SylTextElement.csFinal= result[15];
	SylTextElement.csLeftPhone= result[16]; // chu cai dung truoc am tiet hien tai
	SylTextElement.csRightPhone= result[17];
	SylTextElement.csInitialType= result[18];	
	SylTextElement.csMiddleType= result[19];	
	SylTextElement.csNucleusType= result[20];	
	SylTextElement.csFinalType= result[21];
	SylTextElement.csLeftPhoneType= result[22];	
	SylTextElement.csRightPhoneType= result[23];	
	SylTextElement.fEnergy= atof(result[24]);
	//cout<<SylTextElement.fEnergy<<endl;
	SylTextArray.Add(SylTextElement);

	if(strcmp(SylTextElement.csSyllableName,"SIL")==0)
	{
		//WriteToTextFile(",");
	}else if(strcmp(SylTextElement.csSyllableName,"SILS")==0)
	{
		//WriteToTextFile(".");
	}else if(strcmp(SylTextElement.csSyllableName,"SILP")==0)
	{
		//WriteToTextFile(".\n");
	}else 
	{
		//WriteToTextFile(SylTextElement.csSyllableName);
	}

	
	/////////////////


	return true;	
}
////
CString  CTextHandle::NormalizeString(CString cstr)
{
	int nIsDoubleSpace = 1;
	CString result = "";
	cstr.Replace("\t"," ");
	nIsDoubleSpace = cstr.Find("  ");
	while(nIsDoubleSpace!=-1)
	{
		cstr.Replace("  "," ");
		nIsDoubleSpace = cstr.Find("  ");
	}
	cstr.TrimLeft();
	cstr.TrimRight();	
	return cstr;
}

/////////////////
 /*CArray<SYLLABLEFULL,SYLLABLEFULL> CTextHandle::FindInTextDB(CString cstr, CArray<SYLLABLEFULL,SYLLABLEFULL> &SylTextArray)
{
	CArray<SYLLABLEFULL,SYLLABLEFULL> SylResultArray;
	SylResultArray.Add(SylTextArray.ElementAt(0));
	return SylResultArray;
} */

/////////////////
void CTextHandle::GetSylArrayPosInTextDB(CArray<UNITINFOFULL, UNITINFOFULL> &SyllableArray)
{
	int nSASize = SyllableArray.GetSize();
	int i = 0, j = 0;
	//cout<<nSASize<<endl;
	for(i = 0;i<nSASize;i++)
	{
		/* for(j=0;j<i;j++)
		{
			if(SyllableArray.ElementAt(i).cUnitName.Compare(SyllableArray.ElementAt(j).cUnitName) ==0)
			{
				SyllableArray.ElementAt(i).nPosOfSylInTextDB = SyllableArray.ElementAt(j).nPosOfSylInTextDB;
				break;
			}

		} */
		//cout<<"cUnitName "<<SyllableArray.ElementAt(i).cUnitName<<endl;
		GetSylPosInTextDB(SyllableArray.ElementAt(i));
	}
	///////////
	/* for(i = 0;i<nSASize;i++)
	{
		cout<<SyllableArray.ElementAt(i).nPosOfSylInTextDB[0]<<endl;
	} */


}
////////////////////////////////////////////////////////////////////////////////////////
//tim vi tri am tiet Syllable trong SylTextArray
// luu vao nPosOfSylInTextDB cua Element trong SyllableArray
void CTextHandle::GetSylPosInTextDB(UNITINFOFULL &SyllableElement)
{
	int nSTSize = SylTextArray.GetSize();
	int i = 0 , j = 0;
	//cout <<" : "<<nSASize<<endl;
	for(i =0; i<nSTSize;i++)
	{
		
		if((SyllableElement.cUnitName.Compare("SIL")==0)
			||(SyllableElement.cUnitName.Compare("SILS")==0)
				||(SyllableElement.cUnitName.Compare("SILP")==0)) break;
		//if(j>=199) break;//neu am tiet la SIL thi so luong > 200 -> ko can thiet
		if(SyllableElement.cUnitName.Compare(SylTextArray.ElementAt(i).csSyllableName)==0)
		{
		 	//WriteToTextFile(SyllableElement.cUnitName);
			//cout<<"SyllableElement.cUnitName: "<<SyllableElement.cUnitName<<"; i=: "<<i<<"; j=: "<<j<<endl;
			SyllableElement.nPosOfSylInTextDB[j] = i;
			j++;
		}
	}	
}